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