1*d6f3710aSGarlic Tseng /* 2*d6f3710aSGarlic Tseng * mt2701-afe-clock-ctrl.c -- Mediatek 2701 afe clock ctrl 3*d6f3710aSGarlic Tseng * 4*d6f3710aSGarlic Tseng * Copyright (c) 2016 MediaTek Inc. 5*d6f3710aSGarlic Tseng * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6*d6f3710aSGarlic Tseng * 7*d6f3710aSGarlic Tseng * This program is free software; you can redistribute it and/or modify 8*d6f3710aSGarlic Tseng * it under the terms of the GNU General Public License version 2 and 9*d6f3710aSGarlic Tseng * only version 2 as published by the Free Software Foundation. 10*d6f3710aSGarlic Tseng * 11*d6f3710aSGarlic Tseng * This program is distributed in the hope that it will be useful, 12*d6f3710aSGarlic Tseng * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*d6f3710aSGarlic Tseng * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*d6f3710aSGarlic Tseng * GNU General Public License for more details. 15*d6f3710aSGarlic Tseng */ 16*d6f3710aSGarlic Tseng 17*d6f3710aSGarlic Tseng #include <sound/soc.h> 18*d6f3710aSGarlic Tseng #include <linux/regmap.h> 19*d6f3710aSGarlic Tseng #include <linux/pm_runtime.h> 20*d6f3710aSGarlic Tseng 21*d6f3710aSGarlic Tseng #include "mt2701-afe-common.h" 22*d6f3710aSGarlic Tseng #include "mt2701-afe-clock-ctrl.h" 23*d6f3710aSGarlic Tseng 24*d6f3710aSGarlic Tseng static const char *aud_clks[MT2701_CLOCK_NUM] = { 25*d6f3710aSGarlic Tseng [MT2701_AUD_INFRA_SYS_AUDIO] = "infra_sys_audio_clk", 26*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_MUX1_SEL] = "top_audio_mux1_sel", 27*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_MUX2_SEL] = "top_audio_mux2_sel", 28*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_MUX1_DIV] = "top_audio_mux1_div", 29*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_MUX2_DIV] = "top_audio_mux2_div", 30*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_48K_TIMING] = "top_audio_48k_timing", 31*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_44K_TIMING] = "top_audio_44k_timing", 32*d6f3710aSGarlic Tseng [MT2701_AUD_AUDPLL_MUX_SEL] = "top_audpll_mux_sel", 33*d6f3710aSGarlic Tseng [MT2701_AUD_APLL_SEL] = "top_apll_sel", 34*d6f3710aSGarlic Tseng [MT2701_AUD_AUD1PLL_98M] = "top_aud1_pll_98M", 35*d6f3710aSGarlic Tseng [MT2701_AUD_AUD2PLL_90M] = "top_aud2_pll_90M", 36*d6f3710aSGarlic Tseng [MT2701_AUD_HADDS2PLL_98M] = "top_hadds2_pll_98M", 37*d6f3710aSGarlic Tseng [MT2701_AUD_HADDS2PLL_294M] = "top_hadds2_pll_294M", 38*d6f3710aSGarlic Tseng [MT2701_AUD_AUDPLL] = "top_audpll", 39*d6f3710aSGarlic Tseng [MT2701_AUD_AUDPLL_D4] = "top_audpll_d4", 40*d6f3710aSGarlic Tseng [MT2701_AUD_AUDPLL_D8] = "top_audpll_d8", 41*d6f3710aSGarlic Tseng [MT2701_AUD_AUDPLL_D16] = "top_audpll_d16", 42*d6f3710aSGarlic Tseng [MT2701_AUD_AUDPLL_D24] = "top_audpll_d24", 43*d6f3710aSGarlic Tseng [MT2701_AUD_AUDINTBUS] = "top_audintbus_sel", 44*d6f3710aSGarlic Tseng [MT2701_AUD_CLK_26M] = "clk_26m", 45*d6f3710aSGarlic Tseng [MT2701_AUD_SYSPLL1_D4] = "top_syspll1_d4", 46*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K1_SRC_SEL] = "top_aud_k1_src_sel", 47*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K2_SRC_SEL] = "top_aud_k2_src_sel", 48*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K3_SRC_SEL] = "top_aud_k3_src_sel", 49*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K4_SRC_SEL] = "top_aud_k4_src_sel", 50*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K5_SRC_SEL] = "top_aud_k5_src_sel", 51*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K6_SRC_SEL] = "top_aud_k6_src_sel", 52*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K1_SRC_DIV] = "top_aud_k1_src_div", 53*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K2_SRC_DIV] = "top_aud_k2_src_div", 54*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K3_SRC_DIV] = "top_aud_k3_src_div", 55*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K4_SRC_DIV] = "top_aud_k4_src_div", 56*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K5_SRC_DIV] = "top_aud_k5_src_div", 57*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_K6_SRC_DIV] = "top_aud_k6_src_div", 58*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_I2S1_MCLK] = "top_aud_i2s1_mclk", 59*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_I2S2_MCLK] = "top_aud_i2s2_mclk", 60*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_I2S3_MCLK] = "top_aud_i2s3_mclk", 61*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_I2S4_MCLK] = "top_aud_i2s4_mclk", 62*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_I2S5_MCLK] = "top_aud_i2s5_mclk", 63*d6f3710aSGarlic Tseng [MT2701_AUD_AUD_I2S6_MCLK] = "top_aud_i2s6_mclk", 64*d6f3710aSGarlic Tseng [MT2701_AUD_ASM_M_SEL] = "top_asm_m_sel", 65*d6f3710aSGarlic Tseng [MT2701_AUD_ASM_H_SEL] = "top_asm_h_sel", 66*d6f3710aSGarlic Tseng [MT2701_AUD_UNIVPLL2_D4] = "top_univpll2_d4", 67*d6f3710aSGarlic Tseng [MT2701_AUD_UNIVPLL2_D2] = "top_univpll2_d2", 68*d6f3710aSGarlic Tseng [MT2701_AUD_SYSPLL_D5] = "top_syspll_d5", 69*d6f3710aSGarlic Tseng }; 70*d6f3710aSGarlic Tseng 71*d6f3710aSGarlic Tseng int mt2701_init_clock(struct mtk_base_afe *afe) 72*d6f3710aSGarlic Tseng { 73*d6f3710aSGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 74*d6f3710aSGarlic Tseng int i = 0; 75*d6f3710aSGarlic Tseng 76*d6f3710aSGarlic Tseng for (i = 0; i < MT2701_CLOCK_NUM; i++) { 77*d6f3710aSGarlic Tseng afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]); 78*d6f3710aSGarlic Tseng if (IS_ERR(aud_clks[i])) { 79*d6f3710aSGarlic Tseng dev_warn(afe->dev, "%s devm_clk_get %s fail\n", 80*d6f3710aSGarlic Tseng __func__, aud_clks[i]); 81*d6f3710aSGarlic Tseng return PTR_ERR(aud_clks[i]); 82*d6f3710aSGarlic Tseng } 83*d6f3710aSGarlic Tseng } 84*d6f3710aSGarlic Tseng 85*d6f3710aSGarlic Tseng return 0; 86*d6f3710aSGarlic Tseng } 87*d6f3710aSGarlic Tseng 88*d6f3710aSGarlic Tseng int mt2701_afe_enable_clock(struct mtk_base_afe *afe) 89*d6f3710aSGarlic Tseng { 90*d6f3710aSGarlic Tseng int ret = 0; 91*d6f3710aSGarlic Tseng 92*d6f3710aSGarlic Tseng ret = mt2701_turn_on_a1sys_clock(afe); 93*d6f3710aSGarlic Tseng if (ret) { 94*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s turn_on_a1sys_clock fail %d\n", 95*d6f3710aSGarlic Tseng __func__, ret); 96*d6f3710aSGarlic Tseng return ret; 97*d6f3710aSGarlic Tseng } 98*d6f3710aSGarlic Tseng 99*d6f3710aSGarlic Tseng ret = mt2701_turn_on_a2sys_clock(afe); 100*d6f3710aSGarlic Tseng if (ret) { 101*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s turn_on_a2sys_clock fail %d\n", 102*d6f3710aSGarlic Tseng __func__, ret); 103*d6f3710aSGarlic Tseng mt2701_turn_off_a1sys_clock(afe); 104*d6f3710aSGarlic Tseng return ret; 105*d6f3710aSGarlic Tseng } 106*d6f3710aSGarlic Tseng 107*d6f3710aSGarlic Tseng ret = mt2701_turn_on_afe_clock(afe); 108*d6f3710aSGarlic Tseng if (ret) { 109*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s turn_on_afe_clock fail %d\n", 110*d6f3710aSGarlic Tseng __func__, ret); 111*d6f3710aSGarlic Tseng mt2701_turn_off_a1sys_clock(afe); 112*d6f3710aSGarlic Tseng mt2701_turn_off_a2sys_clock(afe); 113*d6f3710aSGarlic Tseng return ret; 114*d6f3710aSGarlic Tseng } 115*d6f3710aSGarlic Tseng 116*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, ASYS_TOP_CON, 117*d6f3710aSGarlic Tseng AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 118*d6f3710aSGarlic Tseng AUDIO_TOP_CON0_A1SYS_A2SYS_ON); 119*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AFE_DAC_CON0, 120*d6f3710aSGarlic Tseng AFE_DAC_CON0_AFE_ON, 121*d6f3710aSGarlic Tseng AFE_DAC_CON0_AFE_ON); 122*d6f3710aSGarlic Tseng regmap_write(afe->regmap, PWR2_TOP_CON, 123*d6f3710aSGarlic Tseng PWR2_TOP_CON_INIT_VAL); 124*d6f3710aSGarlic Tseng regmap_write(afe->regmap, PWR1_ASM_CON1, 125*d6f3710aSGarlic Tseng PWR1_ASM_CON1_INIT_VAL); 126*d6f3710aSGarlic Tseng regmap_write(afe->regmap, PWR2_ASM_CON1, 127*d6f3710aSGarlic Tseng PWR2_ASM_CON1_INIT_VAL); 128*d6f3710aSGarlic Tseng 129*d6f3710aSGarlic Tseng return 0; 130*d6f3710aSGarlic Tseng } 131*d6f3710aSGarlic Tseng 132*d6f3710aSGarlic Tseng void mt2701_afe_disable_clock(struct mtk_base_afe *afe) 133*d6f3710aSGarlic Tseng { 134*d6f3710aSGarlic Tseng mt2701_turn_off_afe_clock(afe); 135*d6f3710aSGarlic Tseng mt2701_turn_off_a1sys_clock(afe); 136*d6f3710aSGarlic Tseng mt2701_turn_off_a2sys_clock(afe); 137*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, ASYS_TOP_CON, 138*d6f3710aSGarlic Tseng AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0); 139*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AFE_DAC_CON0, 140*d6f3710aSGarlic Tseng AFE_DAC_CON0_AFE_ON, 0); 141*d6f3710aSGarlic Tseng } 142*d6f3710aSGarlic Tseng 143*d6f3710aSGarlic Tseng int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe) 144*d6f3710aSGarlic Tseng { 145*d6f3710aSGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 146*d6f3710aSGarlic Tseng int ret = 0; 147*d6f3710aSGarlic Tseng 148*d6f3710aSGarlic Tseng /* Set Mux */ 149*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); 150*d6f3710aSGarlic Tseng if (ret) { 151*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 152*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret); 153*d6f3710aSGarlic Tseng goto A1SYS_CLK_AUD_MUX1_SEL_ERR; 154*d6f3710aSGarlic Tseng } 155*d6f3710aSGarlic Tseng 156*d6f3710aSGarlic Tseng ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL], 157*d6f3710aSGarlic Tseng afe_priv->clocks[MT2701_AUD_AUD1PLL_98M]); 158*d6f3710aSGarlic Tseng if (ret) { 159*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, 160*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD_MUX1_SEL], 161*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD1PLL_98M], ret); 162*d6f3710aSGarlic Tseng goto A1SYS_CLK_AUD_MUX1_SEL_ERR; 163*d6f3710aSGarlic Tseng } 164*d6f3710aSGarlic Tseng 165*d6f3710aSGarlic Tseng /* Set Divider */ 166*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); 167*d6f3710aSGarlic Tseng if (ret) { 168*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 169*d6f3710aSGarlic Tseng __func__, 170*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD_MUX1_DIV], 171*d6f3710aSGarlic Tseng ret); 172*d6f3710aSGarlic Tseng goto A1SYS_CLK_AUD_MUX1_DIV_ERR; 173*d6f3710aSGarlic Tseng } 174*d6f3710aSGarlic Tseng 175*d6f3710aSGarlic Tseng ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV], 176*d6f3710aSGarlic Tseng MT2701_AUD_AUD_MUX1_DIV_RATE); 177*d6f3710aSGarlic Tseng if (ret) { 178*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__, 179*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD_MUX1_DIV], 180*d6f3710aSGarlic Tseng MT2701_AUD_AUD_MUX1_DIV_RATE, ret); 181*d6f3710aSGarlic Tseng goto A1SYS_CLK_AUD_MUX1_DIV_ERR; 182*d6f3710aSGarlic Tseng } 183*d6f3710aSGarlic Tseng 184*d6f3710aSGarlic Tseng /* Enable clock gate */ 185*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); 186*d6f3710aSGarlic Tseng if (ret) { 187*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 188*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_AUD_48K_TIMING], ret); 189*d6f3710aSGarlic Tseng goto A1SYS_CLK_AUD_48K_ERR; 190*d6f3710aSGarlic Tseng } 191*d6f3710aSGarlic Tseng 192*d6f3710aSGarlic Tseng /* Enable infra audio */ 193*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 194*d6f3710aSGarlic Tseng if (ret) { 195*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 196*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); 197*d6f3710aSGarlic Tseng goto A1SYS_CLK_INFRA_ERR; 198*d6f3710aSGarlic Tseng } 199*d6f3710aSGarlic Tseng 200*d6f3710aSGarlic Tseng return 0; 201*d6f3710aSGarlic Tseng 202*d6f3710aSGarlic Tseng A1SYS_CLK_INFRA_ERR: 203*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 204*d6f3710aSGarlic Tseng A1SYS_CLK_AUD_48K_ERR: 205*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); 206*d6f3710aSGarlic Tseng A1SYS_CLK_AUD_MUX1_DIV_ERR: 207*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); 208*d6f3710aSGarlic Tseng A1SYS_CLK_AUD_MUX1_SEL_ERR: 209*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); 210*d6f3710aSGarlic Tseng 211*d6f3710aSGarlic Tseng return ret; 212*d6f3710aSGarlic Tseng } 213*d6f3710aSGarlic Tseng 214*d6f3710aSGarlic Tseng void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe) 215*d6f3710aSGarlic Tseng { 216*d6f3710aSGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 217*d6f3710aSGarlic Tseng 218*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 219*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); 220*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); 221*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); 222*d6f3710aSGarlic Tseng } 223*d6f3710aSGarlic Tseng 224*d6f3710aSGarlic Tseng int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe) 225*d6f3710aSGarlic Tseng { 226*d6f3710aSGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 227*d6f3710aSGarlic Tseng int ret = 0; 228*d6f3710aSGarlic Tseng 229*d6f3710aSGarlic Tseng /* Set Mux */ 230*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); 231*d6f3710aSGarlic Tseng if (ret) { 232*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 233*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret); 234*d6f3710aSGarlic Tseng goto A2SYS_CLK_AUD_MUX2_SEL_ERR; 235*d6f3710aSGarlic Tseng } 236*d6f3710aSGarlic Tseng 237*d6f3710aSGarlic Tseng ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL], 238*d6f3710aSGarlic Tseng afe_priv->clocks[MT2701_AUD_AUD2PLL_90M]); 239*d6f3710aSGarlic Tseng if (ret) { 240*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, 241*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD_MUX2_SEL], 242*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD2PLL_90M], ret); 243*d6f3710aSGarlic Tseng goto A2SYS_CLK_AUD_MUX2_SEL_ERR; 244*d6f3710aSGarlic Tseng } 245*d6f3710aSGarlic Tseng 246*d6f3710aSGarlic Tseng /* Set Divider */ 247*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); 248*d6f3710aSGarlic Tseng if (ret) { 249*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 250*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_AUD_MUX2_DIV], ret); 251*d6f3710aSGarlic Tseng goto A2SYS_CLK_AUD_MUX2_DIV_ERR; 252*d6f3710aSGarlic Tseng } 253*d6f3710aSGarlic Tseng 254*d6f3710aSGarlic Tseng ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV], 255*d6f3710aSGarlic Tseng MT2701_AUD_AUD_MUX2_DIV_RATE); 256*d6f3710aSGarlic Tseng if (ret) { 257*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__, 258*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD_MUX2_DIV], 259*d6f3710aSGarlic Tseng MT2701_AUD_AUD_MUX2_DIV_RATE, ret); 260*d6f3710aSGarlic Tseng goto A2SYS_CLK_AUD_MUX2_DIV_ERR; 261*d6f3710aSGarlic Tseng } 262*d6f3710aSGarlic Tseng 263*d6f3710aSGarlic Tseng /* Enable clock gate */ 264*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); 265*d6f3710aSGarlic Tseng if (ret) { 266*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 267*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_AUD_44K_TIMING], ret); 268*d6f3710aSGarlic Tseng goto A2SYS_CLK_AUD_44K_ERR; 269*d6f3710aSGarlic Tseng } 270*d6f3710aSGarlic Tseng 271*d6f3710aSGarlic Tseng /* Enable infra audio */ 272*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 273*d6f3710aSGarlic Tseng if (ret) { 274*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 275*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); 276*d6f3710aSGarlic Tseng goto A2SYS_CLK_INFRA_ERR; 277*d6f3710aSGarlic Tseng } 278*d6f3710aSGarlic Tseng 279*d6f3710aSGarlic Tseng return 0; 280*d6f3710aSGarlic Tseng 281*d6f3710aSGarlic Tseng A2SYS_CLK_INFRA_ERR: 282*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 283*d6f3710aSGarlic Tseng A2SYS_CLK_AUD_44K_ERR: 284*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); 285*d6f3710aSGarlic Tseng A2SYS_CLK_AUD_MUX2_DIV_ERR: 286*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); 287*d6f3710aSGarlic Tseng A2SYS_CLK_AUD_MUX2_SEL_ERR: 288*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); 289*d6f3710aSGarlic Tseng 290*d6f3710aSGarlic Tseng return ret; 291*d6f3710aSGarlic Tseng } 292*d6f3710aSGarlic Tseng 293*d6f3710aSGarlic Tseng void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe) 294*d6f3710aSGarlic Tseng { 295*d6f3710aSGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 296*d6f3710aSGarlic Tseng 297*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 298*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); 299*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); 300*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); 301*d6f3710aSGarlic Tseng } 302*d6f3710aSGarlic Tseng 303*d6f3710aSGarlic Tseng int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe) 304*d6f3710aSGarlic Tseng { 305*d6f3710aSGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 306*d6f3710aSGarlic Tseng int ret; 307*d6f3710aSGarlic Tseng 308*d6f3710aSGarlic Tseng /* enable INFRA_SYS */ 309*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 310*d6f3710aSGarlic Tseng if (ret) { 311*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 312*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); 313*d6f3710aSGarlic Tseng goto AFE_AUD_INFRA_ERR; 314*d6f3710aSGarlic Tseng } 315*d6f3710aSGarlic Tseng 316*d6f3710aSGarlic Tseng /* Set MT2701_AUD_AUDINTBUS to MT2701_AUD_SYSPLL1_D4 */ 317*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); 318*d6f3710aSGarlic Tseng if (ret) { 319*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 320*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_AUDINTBUS], ret); 321*d6f3710aSGarlic Tseng goto AFE_AUD_AUDINTBUS_ERR; 322*d6f3710aSGarlic Tseng } 323*d6f3710aSGarlic Tseng 324*d6f3710aSGarlic Tseng ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUDINTBUS], 325*d6f3710aSGarlic Tseng afe_priv->clocks[MT2701_AUD_SYSPLL1_D4]); 326*d6f3710aSGarlic Tseng if (ret) { 327*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, 328*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUDINTBUS], 329*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_SYSPLL1_D4], ret); 330*d6f3710aSGarlic Tseng goto AFE_AUD_AUDINTBUS_ERR; 331*d6f3710aSGarlic Tseng } 332*d6f3710aSGarlic Tseng 333*d6f3710aSGarlic Tseng /* Set MT2701_AUD_ASM_H_SEL to MT2701_AUD_UNIVPLL2_D2 */ 334*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); 335*d6f3710aSGarlic Tseng if (ret) { 336*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 337*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_ASM_H_SEL], ret); 338*d6f3710aSGarlic Tseng goto AFE_AUD_ASM_H_ERR; 339*d6f3710aSGarlic Tseng } 340*d6f3710aSGarlic Tseng 341*d6f3710aSGarlic Tseng ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_H_SEL], 342*d6f3710aSGarlic Tseng afe_priv->clocks[MT2701_AUD_UNIVPLL2_D2]); 343*d6f3710aSGarlic Tseng if (ret) { 344*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, 345*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_ASM_H_SEL], 346*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_UNIVPLL2_D2], ret); 347*d6f3710aSGarlic Tseng goto AFE_AUD_ASM_H_ERR; 348*d6f3710aSGarlic Tseng } 349*d6f3710aSGarlic Tseng 350*d6f3710aSGarlic Tseng /* Set MT2701_AUD_ASM_M_SEL to MT2701_AUD_UNIVPLL2_D4 */ 351*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); 352*d6f3710aSGarlic Tseng if (ret) { 353*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 354*d6f3710aSGarlic Tseng __func__, aud_clks[MT2701_AUD_ASM_M_SEL], ret); 355*d6f3710aSGarlic Tseng goto AFE_AUD_ASM_M_ERR; 356*d6f3710aSGarlic Tseng } 357*d6f3710aSGarlic Tseng 358*d6f3710aSGarlic Tseng ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_M_SEL], 359*d6f3710aSGarlic Tseng afe_priv->clocks[MT2701_AUD_UNIVPLL2_D4]); 360*d6f3710aSGarlic Tseng if (ret) { 361*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, 362*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_ASM_M_SEL], 363*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_UNIVPLL2_D4], ret); 364*d6f3710aSGarlic Tseng goto AFE_AUD_ASM_M_ERR; 365*d6f3710aSGarlic Tseng } 366*d6f3710aSGarlic Tseng 367*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 368*d6f3710aSGarlic Tseng AUDIO_TOP_CON0_PDN_AFE, 0); 369*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 370*d6f3710aSGarlic Tseng AUDIO_TOP_CON0_PDN_APLL_CK, 0); 371*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 372*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_A1SYS, 0); 373*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 374*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_A2SYS, 0); 375*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 376*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_AFE_CONN, 0); 377*d6f3710aSGarlic Tseng 378*d6f3710aSGarlic Tseng return 0; 379*d6f3710aSGarlic Tseng 380*d6f3710aSGarlic Tseng AFE_AUD_ASM_M_ERR: 381*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); 382*d6f3710aSGarlic Tseng AFE_AUD_ASM_H_ERR: 383*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); 384*d6f3710aSGarlic Tseng AFE_AUD_AUDINTBUS_ERR: 385*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); 386*d6f3710aSGarlic Tseng AFE_AUD_INFRA_ERR: 387*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 388*d6f3710aSGarlic Tseng 389*d6f3710aSGarlic Tseng return ret; 390*d6f3710aSGarlic Tseng } 391*d6f3710aSGarlic Tseng 392*d6f3710aSGarlic Tseng void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe) 393*d6f3710aSGarlic Tseng { 394*d6f3710aSGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 395*d6f3710aSGarlic Tseng 396*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); 397*d6f3710aSGarlic Tseng 398*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); 399*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); 400*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); 401*d6f3710aSGarlic Tseng 402*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 403*d6f3710aSGarlic Tseng AUDIO_TOP_CON0_PDN_AFE, AUDIO_TOP_CON0_PDN_AFE); 404*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 405*d6f3710aSGarlic Tseng AUDIO_TOP_CON0_PDN_APLL_CK, 406*d6f3710aSGarlic Tseng AUDIO_TOP_CON0_PDN_APLL_CK); 407*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 408*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_A1SYS, 409*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_A1SYS); 410*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 411*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_A2SYS, 412*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_A2SYS); 413*d6f3710aSGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 414*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_AFE_CONN, 415*d6f3710aSGarlic Tseng AUDIO_TOP_CON4_PDN_AFE_CONN); 416*d6f3710aSGarlic Tseng } 417*d6f3710aSGarlic Tseng 418*d6f3710aSGarlic Tseng void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, 419*d6f3710aSGarlic Tseng int mclk) 420*d6f3710aSGarlic Tseng { 421*d6f3710aSGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 422*d6f3710aSGarlic Tseng int ret; 423*d6f3710aSGarlic Tseng int aud_src_div_id = MT2701_AUD_AUD_K1_SRC_DIV + id; 424*d6f3710aSGarlic Tseng int aud_src_clk_id = MT2701_AUD_AUD_K1_SRC_SEL + id; 425*d6f3710aSGarlic Tseng 426*d6f3710aSGarlic Tseng /* Set MCLK Kx_SRC_SEL(domain) */ 427*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[aud_src_clk_id]); 428*d6f3710aSGarlic Tseng if (ret) 429*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 430*d6f3710aSGarlic Tseng __func__, aud_clks[aud_src_clk_id], ret); 431*d6f3710aSGarlic Tseng 432*d6f3710aSGarlic Tseng if (domain == 0) { 433*d6f3710aSGarlic Tseng ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id], 434*d6f3710aSGarlic Tseng afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); 435*d6f3710aSGarlic Tseng if (ret) 436*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", 437*d6f3710aSGarlic Tseng __func__, aud_clks[aud_src_clk_id], 438*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret); 439*d6f3710aSGarlic Tseng } else { 440*d6f3710aSGarlic Tseng ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id], 441*d6f3710aSGarlic Tseng afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); 442*d6f3710aSGarlic Tseng if (ret) 443*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", 444*d6f3710aSGarlic Tseng __func__, aud_clks[aud_src_clk_id], 445*d6f3710aSGarlic Tseng aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret); 446*d6f3710aSGarlic Tseng } 447*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[aud_src_clk_id]); 448*d6f3710aSGarlic Tseng 449*d6f3710aSGarlic Tseng /* Set MCLK Kx_SRC_DIV(divider) */ 450*d6f3710aSGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[aud_src_div_id]); 451*d6f3710aSGarlic Tseng if (ret) 452*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", 453*d6f3710aSGarlic Tseng __func__, aud_clks[aud_src_div_id], ret); 454*d6f3710aSGarlic Tseng 455*d6f3710aSGarlic Tseng ret = clk_set_rate(afe_priv->clocks[aud_src_div_id], mclk); 456*d6f3710aSGarlic Tseng if (ret) 457*d6f3710aSGarlic Tseng dev_err(afe->dev, "%s clk_set_rate %s-%d fail %d\n", __func__, 458*d6f3710aSGarlic Tseng aud_clks[aud_src_div_id], mclk, ret); 459*d6f3710aSGarlic Tseng clk_disable_unprepare(afe_priv->clocks[aud_src_div_id]); 460*d6f3710aSGarlic Tseng } 461*d6f3710aSGarlic Tseng 462*d6f3710aSGarlic Tseng MODULE_DESCRIPTION("MT2701 afe clock control"); 463*d6f3710aSGarlic Tseng MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>"); 464*d6f3710aSGarlic Tseng MODULE_LICENSE("GPL v2"); 465