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 i;
29 
30 	for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
31 		afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]);
32 		if (IS_ERR(afe_priv->base_ck[i])) {
33 			dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
34 			return PTR_ERR(afe_priv->base_ck[i]);
35 		}
36 	}
37 
38 	/* Get I2S related clocks */
39 	for (i = 0; i < afe_priv->soc->i2s_num; i++) {
40 		struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
41 		struct clk *i2s_ck;
42 		char name[13];
43 
44 		snprintf(name, sizeof(name), "i2s%d_src_sel", i);
45 		i2s_path->sel_ck = devm_clk_get(afe->dev, name);
46 		if (IS_ERR(i2s_path->sel_ck)) {
47 			dev_err(afe->dev, "failed to get %s\n", name);
48 			return PTR_ERR(i2s_path->sel_ck);
49 		}
50 
51 		snprintf(name, sizeof(name), "i2s%d_src_div", i);
52 		i2s_path->div_ck = devm_clk_get(afe->dev, name);
53 		if (IS_ERR(i2s_path->div_ck)) {
54 			dev_err(afe->dev, "failed to get %s\n", name);
55 			return PTR_ERR(i2s_path->div_ck);
56 		}
57 
58 		snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
59 		i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
60 		if (IS_ERR(i2s_path->mclk_ck)) {
61 			dev_err(afe->dev, "failed to get %s\n", name);
62 			return PTR_ERR(i2s_path->mclk_ck);
63 		}
64 
65 		snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
66 		i2s_ck = devm_clk_get(afe->dev, name);
67 		if (IS_ERR(i2s_ck)) {
68 			dev_err(afe->dev, "failed to get %s\n", name);
69 			return PTR_ERR(i2s_ck);
70 		}
71 		i2s_path->hop_ck[SNDRV_PCM_STREAM_PLAYBACK] = i2s_ck;
72 
73 		snprintf(name, sizeof(name), "i2si%d_hop_ck", i);
74 		i2s_ck = devm_clk_get(afe->dev, name);
75 		if (IS_ERR(i2s_ck)) {
76 			dev_err(afe->dev, "failed to get %s\n", name);
77 			return PTR_ERR(i2s_ck);
78 		}
79 		i2s_path->hop_ck[SNDRV_PCM_STREAM_CAPTURE] = i2s_ck;
80 
81 		snprintf(name, sizeof(name), "asrc%d_out_ck", i);
82 		i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
83 		if (IS_ERR(i2s_path->asrco_ck)) {
84 			dev_err(afe->dev, "failed to get %s\n", name);
85 			return PTR_ERR(i2s_path->asrco_ck);
86 		}
87 	}
88 
89 	/* Some platforms may support BT path */
90 	afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
91 	if (IS_ERR(afe_priv->mrgif_ck)) {
92 		if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
93 			return -EPROBE_DEFER;
94 
95 		afe_priv->mrgif_ck = NULL;
96 	}
97 
98 	return 0;
99 }
100 
101 int mt2701_afe_enable_i2s(struct mtk_base_afe *afe,
102 			  struct mt2701_i2s_path *i2s_path,
103 			  int dir)
104 {
105 	int ret;
106 
107 	ret = clk_prepare_enable(i2s_path->asrco_ck);
108 	if (ret) {
109 		dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret);
110 		return ret;
111 	}
112 
113 	ret = clk_prepare_enable(i2s_path->hop_ck[dir]);
114 	if (ret) {
115 		dev_err(afe->dev, "failed to enable I2S clock %d\n", ret);
116 		goto err_hop_ck;
117 	}
118 
119 	return 0;
120 
121 err_hop_ck:
122 	clk_disable_unprepare(i2s_path->asrco_ck);
123 
124 	return ret;
125 }
126 
127 void mt2701_afe_disable_i2s(struct mtk_base_afe *afe,
128 			    struct mt2701_i2s_path *i2s_path,
129 			    int dir)
130 {
131 	clk_disable_unprepare(i2s_path->hop_ck[dir]);
132 	clk_disable_unprepare(i2s_path->asrco_ck);
133 }
134 
135 int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id)
136 {
137 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
138 	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
139 
140 	return clk_prepare_enable(i2s_path->mclk_ck);
141 }
142 
143 void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id)
144 {
145 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
146 	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
147 
148 	clk_disable_unprepare(i2s_path->mclk_ck);
149 }
150 
151 int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe)
152 {
153 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
154 
155 	return clk_prepare_enable(afe_priv->mrgif_ck);
156 }
157 
158 void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe)
159 {
160 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
161 
162 	clk_disable_unprepare(afe_priv->mrgif_ck);
163 }
164 
165 static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
166 {
167 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
168 	int ret;
169 
170 	/* Enable infra clock gate */
171 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
172 	if (ret)
173 		return ret;
174 
175 	/* Enable top a1sys clock gate */
176 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
177 	if (ret)
178 		goto err_a1sys;
179 
180 	/* Enable top a2sys clock gate */
181 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
182 	if (ret)
183 		goto err_a2sys;
184 
185 	/* Internal clock gates */
186 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
187 	if (ret)
188 		goto err_afe;
189 
190 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
191 	if (ret)
192 		goto err_audio_a1sys;
193 
194 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
195 	if (ret)
196 		goto err_audio_a2sys;
197 
198 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
199 	if (ret)
200 		goto err_afe_conn;
201 
202 	return 0;
203 
204 err_afe_conn:
205 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
206 err_audio_a2sys:
207 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
208 err_audio_a1sys:
209 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
210 err_afe:
211 	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
212 err_a2sys:
213 	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
214 err_a1sys:
215 	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
216 
217 	return ret;
218 }
219 
220 static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
221 {
222 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
223 
224 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
225 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
226 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
227 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
228 	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
229 	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
230 	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
231 }
232 
233 int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
234 {
235 	int ret;
236 
237 	/* Enable audio system */
238 	ret = mt2701_afe_enable_audsys(afe);
239 	if (ret) {
240 		dev_err(afe->dev, "failed to enable audio system %d\n", ret);
241 		return ret;
242 	}
243 
244 	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
245 			   ASYS_TOP_CON_ASYS_TIMING_ON,
246 			   ASYS_TOP_CON_ASYS_TIMING_ON);
247 	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
248 			   AFE_DAC_CON0_AFE_ON,
249 			   AFE_DAC_CON0_AFE_ON);
250 
251 	/* Configure ASRC */
252 	regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL);
253 	regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL);
254 
255 	return 0;
256 }
257 
258 int mt2701_afe_disable_clock(struct mtk_base_afe *afe)
259 {
260 	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
261 			   ASYS_TOP_CON_ASYS_TIMING_ON, 0);
262 	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
263 			   AFE_DAC_CON0_AFE_ON, 0);
264 
265 	mt2701_afe_disable_audsys(afe);
266 
267 	return 0;
268 }
269 
270 int mt2701_mclk_configuration(struct mtk_base_afe *afe, int id)
271 
272 {
273 	struct mt2701_afe_private *priv = afe->platform_priv;
274 	struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id];
275 	int ret = -EINVAL;
276 
277 	/* Set mclk source */
278 	if (!(MT2701_PLL_DOMAIN_0_RATE % i2s_path->mclk_rate))
279 		ret = clk_set_parent(i2s_path->sel_ck,
280 				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
281 	else if (!(MT2701_PLL_DOMAIN_1_RATE % i2s_path->mclk_rate))
282 		ret = clk_set_parent(i2s_path->sel_ck,
283 				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
284 
285 	if (ret) {
286 		dev_err(afe->dev, "failed to set mclk source\n");
287 		return ret;
288 	}
289 
290 	/* Set mclk divider */
291 	ret = clk_set_rate(i2s_path->div_ck, i2s_path->mclk_rate);
292 	if (ret) {
293 		dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
294 		return ret;
295 	}
296 
297 	return 0;
298 }
299