xref: /linux/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c (revision 6c52e58dbdaed2eea6cd10461e6b7fb3de4c99d5)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * mt2701-afe-clock-ctrl.c  --  Mediatek 2701 afe clock ctrl
4  *
5  * Copyright (c) 2016 MediaTek Inc.
6  * Author: Garlic Tseng <garlic.tseng@mediatek.com>
7  *	   Ryder Lee <ryder.lee@mediatek.com>
8  */
9 
10 #include "mt2701-afe-common.h"
11 #include "mt2701-afe-clock-ctrl.h"
12 
13 static const char *const base_clks[] = {
14 	[MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
15 	[MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel",
16 	[MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel",
17 	[MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp",
18 	[MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp",
19 	[MT2701_AUDSYS_AFE] = "audio_afe_pd",
20 	[MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd",
21 	[MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd",
22 	[MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd",
23 };
24 
25 int mt2701_init_clock(struct mtk_base_afe *afe)
26 {
27 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
28 	int i2s_num;
29 	int i;
30 
31 	for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
32 		afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]);
33 		if (IS_ERR(afe_priv->base_ck[i])) {
34 			dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
35 			return PTR_ERR(afe_priv->base_ck[i]);
36 		}
37 	}
38 
39 	i2s_num = min(afe_priv->soc->i2s_num, MT2701_BASE_CLK_NUM);
40 	/* Get I2S related clocks */
41 	for (i = 0; i < i2s_num; i++) {
42 		struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
43 		struct clk *i2s_ck;
44 		char name[13];
45 
46 		snprintf(name, sizeof(name), "i2s%d_src_sel", i);
47 		i2s_path->sel_ck = devm_clk_get(afe->dev, name);
48 		if (IS_ERR(i2s_path->sel_ck)) {
49 			dev_err(afe->dev, "failed to get %s\n", name);
50 			return PTR_ERR(i2s_path->sel_ck);
51 		}
52 
53 		snprintf(name, sizeof(name), "i2s%d_src_div", i);
54 		i2s_path->div_ck = devm_clk_get(afe->dev, name);
55 		if (IS_ERR(i2s_path->div_ck)) {
56 			dev_err(afe->dev, "failed to get %s\n", name);
57 			return PTR_ERR(i2s_path->div_ck);
58 		}
59 
60 		snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
61 		i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
62 		if (IS_ERR(i2s_path->mclk_ck)) {
63 			dev_err(afe->dev, "failed to get %s\n", name);
64 			return PTR_ERR(i2s_path->mclk_ck);
65 		}
66 
67 		snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
68 		i2s_ck = devm_clk_get(afe->dev, name);
69 		if (IS_ERR(i2s_ck)) {
70 			dev_err(afe->dev, "failed to get %s\n", name);
71 			return PTR_ERR(i2s_ck);
72 		}
73 		i2s_path->hop_ck[SNDRV_PCM_STREAM_PLAYBACK] = i2s_ck;
74 
75 		snprintf(name, sizeof(name), "i2si%d_hop_ck", i);
76 		i2s_ck = devm_clk_get(afe->dev, name);
77 		if (IS_ERR(i2s_ck)) {
78 			dev_err(afe->dev, "failed to get %s\n", name);
79 			return PTR_ERR(i2s_ck);
80 		}
81 		i2s_path->hop_ck[SNDRV_PCM_STREAM_CAPTURE] = i2s_ck;
82 
83 		snprintf(name, sizeof(name), "asrc%d_out_ck", i);
84 		i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
85 		if (IS_ERR(i2s_path->asrco_ck)) {
86 			dev_err(afe->dev, "failed to get %s\n", name);
87 			return PTR_ERR(i2s_path->asrco_ck);
88 		}
89 	}
90 
91 	/* Some platforms may support BT path */
92 	afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
93 	if (IS_ERR(afe_priv->mrgif_ck)) {
94 		if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
95 			return -EPROBE_DEFER;
96 
97 		afe_priv->mrgif_ck = NULL;
98 	}
99 
100 	/*
101 	 * Optional HDMI audio clocks. Platforms that do not wire up the
102 	 * HDMI output (e.g. MT2701 devkits using only the I2S BE DAIs)
103 	 * may omit these; in that case the HDMI BE DAI simply cannot be
104 	 * enabled, but the rest of the AFE still probes.
105 	 */
106 	afe_priv->hadds2pll_ck = devm_clk_get_optional(afe->dev, "hadds2pll_294m");
107 	if (IS_ERR(afe_priv->hadds2pll_ck))
108 		return PTR_ERR(afe_priv->hadds2pll_ck);
109 
110 	afe_priv->audio_hdmi_ck = devm_clk_get_optional(afe->dev, "audio_hdmi_pd");
111 	if (IS_ERR(afe_priv->audio_hdmi_ck))
112 		return PTR_ERR(afe_priv->audio_hdmi_ck);
113 
114 	afe_priv->audio_spdf_ck = devm_clk_get_optional(afe->dev, "audio_spdf_pd");
115 	if (IS_ERR(afe_priv->audio_spdf_ck))
116 		return PTR_ERR(afe_priv->audio_spdf_ck);
117 
118 	afe_priv->audio_apll_ck = devm_clk_get_optional(afe->dev, "audio_apll_pd");
119 	if (IS_ERR(afe_priv->audio_apll_ck))
120 		return PTR_ERR(afe_priv->audio_apll_ck);
121 
122 	return 0;
123 }
124 
125 int mt2701_afe_enable_i2s(struct mtk_base_afe *afe,
126 			  struct mt2701_i2s_path *i2s_path,
127 			  int dir)
128 {
129 	int ret;
130 
131 	ret = clk_prepare_enable(i2s_path->asrco_ck);
132 	if (ret) {
133 		dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret);
134 		return ret;
135 	}
136 
137 	ret = clk_prepare_enable(i2s_path->hop_ck[dir]);
138 	if (ret) {
139 		dev_err(afe->dev, "failed to enable I2S clock %d\n", ret);
140 		goto err_hop_ck;
141 	}
142 
143 	return 0;
144 
145 err_hop_ck:
146 	clk_disable_unprepare(i2s_path->asrco_ck);
147 
148 	return ret;
149 }
150 
151 void mt2701_afe_disable_i2s(struct mtk_base_afe *afe,
152 			    struct mt2701_i2s_path *i2s_path,
153 			    int dir)
154 {
155 	clk_disable_unprepare(i2s_path->hop_ck[dir]);
156 	clk_disable_unprepare(i2s_path->asrco_ck);
157 }
158 
159 int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id)
160 {
161 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
162 	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
163 
164 	return clk_prepare_enable(i2s_path->mclk_ck);
165 }
166 
167 void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id)
168 {
169 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
170 	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
171 
172 	clk_disable_unprepare(i2s_path->mclk_ck);
173 }
174 
175 int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe)
176 {
177 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
178 
179 	return clk_prepare_enable(afe_priv->mrgif_ck);
180 }
181 
182 void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe)
183 {
184 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
185 
186 	clk_disable_unprepare(afe_priv->mrgif_ck);
187 }
188 
189 static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
190 {
191 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
192 	int ret;
193 
194 	/* Enable infra clock gate */
195 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
196 	if (ret)
197 		return ret;
198 
199 	/* Enable top a1sys clock gate */
200 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
201 	if (ret)
202 		goto err_a1sys;
203 
204 	/* Enable top a2sys clock gate */
205 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
206 	if (ret)
207 		goto err_a2sys;
208 
209 	/* Internal clock gates */
210 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
211 	if (ret)
212 		goto err_afe;
213 
214 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
215 	if (ret)
216 		goto err_audio_a1sys;
217 
218 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
219 	if (ret)
220 		goto err_audio_a2sys;
221 
222 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
223 	if (ret)
224 		goto err_afe_conn;
225 
226 	return 0;
227 
228 err_afe_conn:
229 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
230 err_audio_a2sys:
231 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
232 err_audio_a1sys:
233 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
234 err_afe:
235 	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
236 err_a2sys:
237 	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
238 err_a1sys:
239 	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
240 
241 	return ret;
242 }
243 
244 static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
245 {
246 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
247 
248 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
249 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
250 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
251 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
252 	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
253 	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
254 	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
255 }
256 
257 int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
258 {
259 	int ret;
260 
261 	/* Enable audio system */
262 	ret = mt2701_afe_enable_audsys(afe);
263 	if (ret) {
264 		dev_err(afe->dev, "failed to enable audio system %d\n", ret);
265 		return ret;
266 	}
267 
268 	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
269 			   ASYS_TOP_CON_ASYS_TIMING_ON,
270 			   ASYS_TOP_CON_ASYS_TIMING_ON);
271 	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
272 			   AFE_DAC_CON0_AFE_ON,
273 			   AFE_DAC_CON0_AFE_ON);
274 
275 	/* Configure ASRC */
276 	regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL);
277 	regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL);
278 
279 	return 0;
280 }
281 
282 int mt2701_afe_disable_clock(struct mtk_base_afe *afe)
283 {
284 	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
285 			   ASYS_TOP_CON_ASYS_TIMING_ON, 0);
286 	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
287 			   AFE_DAC_CON0_AFE_ON, 0);
288 
289 	mt2701_afe_disable_audsys(afe);
290 
291 	return 0;
292 }
293 
294 int mt2701_mclk_configuration(struct mtk_base_afe *afe, int id)
295 
296 {
297 	struct mt2701_afe_private *priv = afe->platform_priv;
298 	struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id];
299 	int ret = -EINVAL;
300 
301 	/* Set mclk source */
302 	if (!(MT2701_PLL_DOMAIN_0_RATE % i2s_path->mclk_rate))
303 		ret = clk_set_parent(i2s_path->sel_ck,
304 				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
305 	else if (!(MT2701_PLL_DOMAIN_1_RATE % i2s_path->mclk_rate))
306 		ret = clk_set_parent(i2s_path->sel_ck,
307 				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
308 
309 	if (ret) {
310 		dev_err(afe->dev, "failed to set mclk source\n");
311 		return ret;
312 	}
313 
314 	/* Set mclk divider */
315 	ret = clk_set_rate(i2s_path->div_ck, i2s_path->mclk_rate);
316 	if (ret) {
317 		dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
318 		return ret;
319 	}
320 
321 	return 0;
322 }
323