1 /* 2 * mt2701-afe-clock-ctrl.c -- Mediatek 2701 afe clock ctrl 3 * 4 * Copyright (c) 2016 MediaTek Inc. 5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 and 9 * only version 2 as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include "mt2701-afe-common.h" 18 #include "mt2701-afe-clock-ctrl.h" 19 20 static const char *const base_clks[] = { 21 [MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk", 22 [MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel", 23 [MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel", 24 [MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp", 25 [MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp", 26 [MT2701_AUDSYS_AFE] = "audio_afe_pd", 27 [MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd", 28 [MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd", 29 [MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd", 30 }; 31 32 int mt2701_init_clock(struct mtk_base_afe *afe) 33 { 34 struct mt2701_afe_private *afe_priv = afe->platform_priv; 35 int i; 36 37 for (i = 0; i < MT2701_BASE_CLK_NUM; i++) { 38 afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]); 39 if (IS_ERR(afe_priv->base_ck[i])) { 40 dev_err(afe->dev, "failed to get %s\n", base_clks[i]); 41 return PTR_ERR(afe_priv->base_ck[i]); 42 } 43 } 44 45 /* Get I2S related clocks */ 46 for (i = 0; i < MT2701_I2S_NUM; i++) { 47 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i]; 48 char name[13]; 49 50 snprintf(name, sizeof(name), "i2s%d_src_sel", i); 51 i2s_path->sel_ck = devm_clk_get(afe->dev, name); 52 if (IS_ERR(i2s_path->sel_ck)) { 53 dev_err(afe->dev, "failed to get %s\n", name); 54 return PTR_ERR(i2s_path->sel_ck); 55 } 56 57 snprintf(name, sizeof(name), "i2s%d_src_div", i); 58 i2s_path->div_ck = devm_clk_get(afe->dev, name); 59 if (IS_ERR(i2s_path->div_ck)) { 60 dev_err(afe->dev, "failed to get %s\n", name); 61 return PTR_ERR(i2s_path->div_ck); 62 } 63 64 snprintf(name, sizeof(name), "i2s%d_mclk_en", i); 65 i2s_path->mclk_ck = devm_clk_get(afe->dev, name); 66 if (IS_ERR(i2s_path->mclk_ck)) { 67 dev_err(afe->dev, "failed to get %s\n", name); 68 return PTR_ERR(i2s_path->mclk_ck); 69 } 70 71 snprintf(name, sizeof(name), "i2so%d_hop_ck", i); 72 i2s_path->hop_ck[I2S_OUT] = devm_clk_get(afe->dev, name); 73 if (IS_ERR(i2s_path->hop_ck[I2S_OUT])) { 74 dev_err(afe->dev, "failed to get %s\n", name); 75 return PTR_ERR(i2s_path->hop_ck[I2S_OUT]); 76 } 77 78 snprintf(name, sizeof(name), "i2si%d_hop_ck", i); 79 i2s_path->hop_ck[I2S_IN] = devm_clk_get(afe->dev, name); 80 if (IS_ERR(i2s_path->hop_ck[I2S_IN])) { 81 dev_err(afe->dev, "failed to get %s\n", name); 82 return PTR_ERR(i2s_path->hop_ck[I2S_IN]); 83 } 84 85 snprintf(name, sizeof(name), "asrc%d_out_ck", i); 86 i2s_path->asrco_ck = devm_clk_get(afe->dev, name); 87 if (IS_ERR(i2s_path->asrco_ck)) { 88 dev_err(afe->dev, "failed to get %s\n", name); 89 return PTR_ERR(i2s_path->asrco_ck); 90 } 91 } 92 93 /* Some platforms may support BT path */ 94 afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd"); 95 if (IS_ERR(afe_priv->mrgif_ck)) { 96 if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER) 97 return -EPROBE_DEFER; 98 99 afe_priv->mrgif_ck = NULL; 100 } 101 102 return 0; 103 } 104 105 int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir) 106 { 107 struct mt2701_afe_private *afe_priv = afe->platform_priv; 108 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; 109 int ret; 110 111 ret = clk_prepare_enable(i2s_path->asrco_ck); 112 if (ret) { 113 dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret); 114 return ret; 115 } 116 117 ret = clk_prepare_enable(i2s_path->hop_ck[dir]); 118 if (ret) { 119 dev_err(afe->dev, "failed to enable I2S clock %d\n", ret); 120 goto err_hop_ck; 121 } 122 123 return 0; 124 125 err_hop_ck: 126 clk_disable_unprepare(i2s_path->asrco_ck); 127 128 return ret; 129 } 130 131 void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir) 132 { 133 struct mt2701_afe_private *afe_priv = afe->platform_priv; 134 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; 135 136 clk_disable_unprepare(i2s_path->hop_ck[dir]); 137 clk_disable_unprepare(i2s_path->asrco_ck); 138 } 139 140 int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id) 141 { 142 struct mt2701_afe_private *afe_priv = afe->platform_priv; 143 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; 144 145 return clk_prepare_enable(i2s_path->mclk_ck); 146 } 147 148 void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id) 149 { 150 struct mt2701_afe_private *afe_priv = afe->platform_priv; 151 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; 152 153 clk_disable_unprepare(i2s_path->mclk_ck); 154 } 155 156 int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe) 157 { 158 struct mt2701_afe_private *afe_priv = afe->platform_priv; 159 160 return clk_prepare_enable(afe_priv->mrgif_ck); 161 } 162 163 void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe) 164 { 165 struct mt2701_afe_private *afe_priv = afe->platform_priv; 166 167 clk_disable_unprepare(afe_priv->mrgif_ck); 168 } 169 170 static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe) 171 { 172 struct mt2701_afe_private *afe_priv = afe->platform_priv; 173 int ret; 174 175 /* Enable infra clock gate */ 176 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]); 177 if (ret) 178 return ret; 179 180 /* Enable top a1sys clock gate */ 181 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]); 182 if (ret) 183 goto err_a1sys; 184 185 /* Enable top a2sys clock gate */ 186 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]); 187 if (ret) 188 goto err_a2sys; 189 190 /* Internal clock gates */ 191 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]); 192 if (ret) 193 goto err_afe; 194 195 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]); 196 if (ret) 197 goto err_audio_a1sys; 198 199 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]); 200 if (ret) 201 goto err_audio_a2sys; 202 203 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]); 204 if (ret) 205 goto err_afe_conn; 206 207 return 0; 208 209 err_afe_conn: 210 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]); 211 err_audio_a2sys: 212 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]); 213 err_audio_a1sys: 214 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]); 215 err_afe: 216 clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]); 217 err_a2sys: 218 clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]); 219 err_a1sys: 220 clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]); 221 222 return ret; 223 } 224 225 static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe) 226 { 227 struct mt2701_afe_private *afe_priv = afe->platform_priv; 228 229 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]); 230 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]); 231 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]); 232 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]); 233 clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]); 234 clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]); 235 clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]); 236 } 237 238 int mt2701_afe_enable_clock(struct mtk_base_afe *afe) 239 { 240 int ret; 241 242 /* Enable audio system */ 243 ret = mt2701_afe_enable_audsys(afe); 244 if (ret) { 245 dev_err(afe->dev, "failed to enable audio system %d\n", ret); 246 return ret; 247 } 248 249 regmap_update_bits(afe->regmap, ASYS_TOP_CON, 250 ASYS_TOP_CON_ASYS_TIMING_ON, 251 ASYS_TOP_CON_ASYS_TIMING_ON); 252 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 253 AFE_DAC_CON0_AFE_ON, 254 AFE_DAC_CON0_AFE_ON); 255 256 /* Configure ASRC */ 257 regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL); 258 regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL); 259 260 return 0; 261 } 262 263 int mt2701_afe_disable_clock(struct mtk_base_afe *afe) 264 { 265 regmap_update_bits(afe->regmap, ASYS_TOP_CON, 266 ASYS_TOP_CON_ASYS_TIMING_ON, 0); 267 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 268 AFE_DAC_CON0_AFE_ON, 0); 269 270 mt2701_afe_disable_audsys(afe); 271 272 return 0; 273 } 274 275 void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, 276 int mclk) 277 { 278 struct mt2701_afe_private *priv = afe->platform_priv; 279 struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id]; 280 int ret; 281 282 /* Set mclk source */ 283 if (domain == 0) 284 ret = clk_set_parent(i2s_path->sel_ck, 285 priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]); 286 else 287 ret = clk_set_parent(i2s_path->sel_ck, 288 priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]); 289 290 if (ret) 291 dev_err(afe->dev, "failed to set domain%d mclk source %d\n", 292 domain, ret); 293 294 /* Set mclk divider */ 295 ret = clk_set_rate(i2s_path->div_ck, mclk); 296 if (ret) 297 dev_err(afe->dev, "failed to set mclk divider %d\n", ret); 298 } 299