GNU Linux-libre 4.19.207-gnu1
[releases.git] / sound / soc / mediatek / mt2701 / mt2701-afe-clock-ctrl.c
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 }