Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/mediatek/mt8189/mt8189-afe-clk.c
38245 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* mt8189-afe-clk.c -- Mediatek 8189 afe clock ctrl
4
*
5
* Copyright (c) 2025 MediaTek Inc.
6
* Author: Darren Ye <[email protected]>
7
*/
8
9
#include <linux/clk.h>
10
#include <linux/regmap.h>
11
#include <linux/mfd/syscon.h>
12
13
#include "mt8189-afe-common.h"
14
#include "mt8189-afe-clk.h"
15
16
/* mck */
17
struct mt8189_mck_div {
18
int m_sel_id;
19
int div_clk_id;
20
};
21
22
static const struct mt8189_mck_div mck_div[MT8189_MCK_NUM] = {
23
[MT8189_I2SIN0_MCK] = {
24
.m_sel_id = MT8189_CLK_TOP_I2SIN0_M_SEL,
25
.div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SIN0,
26
},
27
[MT8189_I2SIN1_MCK] = {
28
.m_sel_id = MT8189_CLK_TOP_I2SIN1_M_SEL,
29
.div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SIN1,
30
},
31
[MT8189_I2SOUT0_MCK] = {
32
.m_sel_id = MT8189_CLK_TOP_I2SOUT0_M_SEL,
33
.div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SOUT0,
34
},
35
[MT8189_I2SOUT1_MCK] = {
36
.m_sel_id = MT8189_CLK_TOP_I2SOUT1_M_SEL,
37
.div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SOUT1,
38
},
39
[MT8189_FMI2S_MCK] = {
40
.m_sel_id = MT8189_CLK_TOP_FMI2S_M_SEL,
41
.div_clk_id = MT8189_CLK_TOP_APLL12_DIV_FMI2S,
42
},
43
[MT8189_TDMOUT_MCK] = {
44
.m_sel_id = MT8189_CLK_TOP_TDMOUT_M_SEL,
45
.div_clk_id = MT8189_CLK_TOP_APLL12_DIV_TDMOUT_M,
46
},
47
[MT8189_TDMOUT_BCK] = {
48
.m_sel_id = -1,
49
.div_clk_id = MT8189_CLK_TOP_APLL12_DIV_TDMOUT_B,
50
},
51
};
52
53
static const char *aud_clks[MT8189_CLK_NUM] = {
54
[MT8189_CLK_TOP_MUX_AUDIOINTBUS] = "top_aud_intbus",
55
[MT8189_CLK_TOP_MUX_AUD_ENG1] = "top_aud_eng1",
56
[MT8189_CLK_TOP_MUX_AUD_ENG2] = "top_aud_eng2",
57
[MT8189_CLK_TOP_MUX_AUDIO_H] = "top_aud_h",
58
/* pll */
59
[MT8189_CLK_TOP_APLL1_CK] = "apll1",
60
[MT8189_CLK_TOP_APLL2_CK] = "apll2",
61
/* divider */
62
[MT8189_CLK_TOP_APLL1_D4] = "apll1_d4",
63
[MT8189_CLK_TOP_APLL2_D4] = "apll2_d4",
64
[MT8189_CLK_TOP_APLL12_DIV_I2SIN0] = "apll12_div_i2sin0",
65
[MT8189_CLK_TOP_APLL12_DIV_I2SIN1] = "apll12_div_i2sin1",
66
[MT8189_CLK_TOP_APLL12_DIV_I2SOUT0] = "apll12_div_i2sout0",
67
[MT8189_CLK_TOP_APLL12_DIV_I2SOUT1] = "apll12_div_i2sout1",
68
[MT8189_CLK_TOP_APLL12_DIV_FMI2S] = "apll12_div_fmi2s",
69
[MT8189_CLK_TOP_APLL12_DIV_TDMOUT_M] = "apll12_div_tdmout_m",
70
[MT8189_CLK_TOP_APLL12_DIV_TDMOUT_B] = "apll12_div_tdmout_b",
71
/* mux */
72
[MT8189_CLK_TOP_MUX_AUD_1] = "top_apll1",
73
[MT8189_CLK_TOP_MUX_AUD_2] = "top_apll2",
74
[MT8189_CLK_TOP_I2SIN0_M_SEL] = "top_i2sin0",
75
[MT8189_CLK_TOP_I2SIN1_M_SEL] = "top_i2sin1",
76
[MT8189_CLK_TOP_I2SOUT0_M_SEL] = "top_i2sout0",
77
[MT8189_CLK_TOP_I2SOUT1_M_SEL] = "top_i2sout1",
78
[MT8189_CLK_TOP_FMI2S_M_SEL] = "top_fmi2s",
79
[MT8189_CLK_TOP_TDMOUT_M_SEL] = "top_dptx",
80
/* top 26m*/
81
[MT8189_CLK_TOP_CLK26M] = "clk26m",
82
/* peri */
83
[MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI] = "aud_slv_ck_peri",
84
[MT8189_CLK_PERAO_AUDIO_MST_CK_PERI] = "aud_mst_ck_peri",
85
[MT8189_CLK_PERAO_INTBUS_CK_PERI] = "aud_intbus_ck_peri",
86
};
87
88
int mt8189_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
89
{
90
int ret;
91
92
ret = clk_prepare_enable(clk);
93
if (ret) {
94
dev_err(afe->dev, "failed to enable clk\n");
95
return ret;
96
}
97
98
return 0;
99
}
100
EXPORT_SYMBOL_GPL(mt8189_afe_enable_clk);
101
102
void mt8189_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk)
103
{
104
if (clk)
105
clk_disable_unprepare(clk);
106
else
107
dev_dbg(afe->dev, "NULL clk\n");
108
}
109
EXPORT_SYMBOL_GPL(mt8189_afe_disable_clk);
110
111
static int mt8189_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
112
unsigned int rate)
113
{
114
int ret;
115
116
if (clk) {
117
ret = clk_set_rate(clk, rate);
118
if (ret) {
119
dev_err(afe->dev, "failed to set clk rate\n");
120
return ret;
121
}
122
}
123
124
return 0;
125
}
126
127
static int mt8189_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
128
struct clk *parent)
129
{
130
int ret;
131
132
if (clk && parent) {
133
ret = clk_set_parent(clk, parent);
134
if (ret) {
135
dev_dbg(afe->dev, "failed to set clk parent %d\n", ret);
136
return ret;
137
}
138
}
139
140
return 0;
141
}
142
143
static unsigned int get_top_cg_reg(unsigned int cg_type)
144
{
145
switch (cg_type) {
146
case MT8189_AUDIO_26M_EN_ON:
147
case MT8189_AUDIO_F3P25M_EN_ON:
148
case MT8189_AUDIO_APLL1_EN_ON:
149
case MT8189_AUDIO_APLL2_EN_ON:
150
return AUDIO_ENGEN_CON0;
151
case MT8189_CG_AUDIO_HOPPING_CK:
152
case MT8189_CG_AUDIO_F26M_CK:
153
case MT8189_CG_APLL1_CK:
154
case MT8189_CG_APLL2_CK:
155
case MT8189_PDN_APLL_TUNER2:
156
case MT8189_PDN_APLL_TUNER1:
157
return AUDIO_TOP_CON4;
158
default:
159
return 0;
160
}
161
}
162
163
static unsigned int get_top_cg_mask(unsigned int cg_type)
164
{
165
switch (cg_type) {
166
case MT8189_AUDIO_26M_EN_ON:
167
return AUDIO_26M_EN_ON_MASK_SFT;
168
case MT8189_AUDIO_F3P25M_EN_ON:
169
return AUDIO_F3P25M_EN_ON_MASK_SFT;
170
case MT8189_AUDIO_APLL1_EN_ON:
171
return AUDIO_APLL1_EN_ON_MASK_SFT;
172
case MT8189_AUDIO_APLL2_EN_ON:
173
return AUDIO_APLL2_EN_ON_MASK_SFT;
174
case MT8189_CG_AUDIO_HOPPING_CK:
175
return CG_AUDIO_HOPPING_CK_MASK_SFT;
176
case MT8189_CG_AUDIO_F26M_CK:
177
return CG_AUDIO_F26M_CK_MASK_SFT;
178
case MT8189_CG_APLL1_CK:
179
return CG_APLL1_CK_MASK_SFT;
180
case MT8189_CG_APLL2_CK:
181
return CG_APLL2_CK_MASK_SFT;
182
case MT8189_PDN_APLL_TUNER2:
183
return PDN_APLL_TUNER2_MASK_SFT;
184
case MT8189_PDN_APLL_TUNER1:
185
return PDN_APLL_TUNER1_MASK_SFT;
186
default:
187
return 0;
188
}
189
}
190
191
static unsigned int get_top_cg_on_val(unsigned int cg_type)
192
{
193
switch (cg_type) {
194
case MT8189_AUDIO_26M_EN_ON:
195
case MT8189_AUDIO_F3P25M_EN_ON:
196
case MT8189_AUDIO_APLL1_EN_ON:
197
case MT8189_AUDIO_APLL2_EN_ON:
198
return get_top_cg_mask(cg_type);
199
case MT8189_CG_AUDIO_HOPPING_CK:
200
case MT8189_CG_AUDIO_F26M_CK:
201
case MT8189_CG_APLL1_CK:
202
case MT8189_CG_APLL2_CK:
203
case MT8189_PDN_APLL_TUNER2:
204
case MT8189_PDN_APLL_TUNER1:
205
return 0;
206
default:
207
return 0;
208
}
209
}
210
211
static unsigned int get_top_cg_off_val(unsigned int cg_type)
212
{
213
switch (cg_type) {
214
case MT8189_AUDIO_26M_EN_ON:
215
case MT8189_AUDIO_F3P25M_EN_ON:
216
case MT8189_AUDIO_APLL1_EN_ON:
217
case MT8189_AUDIO_APLL2_EN_ON:
218
return 0;
219
case MT8189_CG_AUDIO_HOPPING_CK:
220
case MT8189_CG_AUDIO_F26M_CK:
221
case MT8189_CG_APLL1_CK:
222
case MT8189_CG_APLL2_CK:
223
case MT8189_PDN_APLL_TUNER2:
224
case MT8189_PDN_APLL_TUNER1:
225
return get_top_cg_mask(cg_type);
226
default:
227
return get_top_cg_mask(cg_type);
228
}
229
}
230
231
static int mt8189_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
232
{
233
unsigned int reg = get_top_cg_reg(cg_type);
234
unsigned int mask = get_top_cg_mask(cg_type);
235
unsigned int val = get_top_cg_on_val(cg_type);
236
237
if (!afe->regmap) {
238
dev_err(afe->dev, "afe regmap is null !!!\n");
239
return 0;
240
}
241
242
dev_dbg(afe->dev, "reg: 0x%x, mask: 0x%x, val: 0x%x\n", reg, mask, val);
243
244
return regmap_update_bits(afe->regmap, reg, mask, val);
245
}
246
247
static void mt8189_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
248
{
249
unsigned int reg = get_top_cg_reg(cg_type);
250
unsigned int mask = get_top_cg_mask(cg_type);
251
unsigned int val = get_top_cg_off_val(cg_type);
252
253
if (!afe->regmap) {
254
dev_warn(afe->dev, "skip regmap\n");
255
return;
256
}
257
258
dev_dbg(afe->dev, "reg: 0x%x, mask: 0x%x, val: 0x%x\n", reg, mask, val);
259
regmap_update_bits(afe->regmap, reg, mask, val);
260
}
261
262
static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable)
263
{
264
struct mt8189_afe_private *afe_priv = afe->platform_priv;
265
int ret;
266
267
dev_dbg(afe->dev, "enable: %d\n", enable);
268
269
if (enable) {
270
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]);
271
if (ret)
272
return ret;
273
274
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1],
275
afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]);
276
if (ret)
277
goto clk_ck_mux_aud1_parent_err;
278
279
/* 180.6336 / 4 = 45.1584MHz */
280
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]);
281
if (ret)
282
goto clk_ck_mux_eng1_err;
283
284
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1],
285
afe_priv->clk[MT8189_CLK_TOP_APLL1_D4]);
286
if (ret)
287
goto clk_ck_mux_eng1_parent_err;
288
289
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
290
if (ret)
291
goto clk_ck_mux_audio_h_err;
292
293
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H],
294
afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]);
295
if (ret)
296
goto clk_ck_mux_audio_h_parent_err;
297
} else {
298
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1],
299
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
300
301
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]);
302
303
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1],
304
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
305
306
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]);
307
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H],
308
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
309
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
310
}
311
312
return 0;
313
314
clk_ck_mux_audio_h_parent_err:
315
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
316
clk_ck_mux_audio_h_err:
317
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1],
318
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
319
clk_ck_mux_eng1_parent_err:
320
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]);
321
clk_ck_mux_eng1_err:
322
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1],
323
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
324
clk_ck_mux_aud1_parent_err:
325
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]);
326
327
return ret;
328
}
329
330
static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable)
331
{
332
struct mt8189_afe_private *afe_priv = afe->platform_priv;
333
int ret;
334
335
dev_dbg(afe->dev, "enable: %d\n", enable);
336
337
if (enable) {
338
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]);
339
if (ret)
340
return ret;
341
342
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2],
343
afe_priv->clk[MT8189_CLK_TOP_APLL2_CK]);
344
if (ret)
345
goto clk_ck_mux_aud2_parent_err;
346
347
/* 196.608 / 4 = 49.152MHz */
348
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]);
349
if (ret)
350
goto clk_ck_mux_eng2_err;
351
352
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2],
353
afe_priv->clk[MT8189_CLK_TOP_APLL2_D4]);
354
if (ret)
355
goto clk_ck_mux_eng2_parent_err;
356
357
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
358
if (ret)
359
goto clk_ck_mux_audio_h_err;
360
361
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H],
362
afe_priv->clk[MT8189_CLK_TOP_APLL2_CK]);
363
if (ret)
364
goto clk_ck_mux_audio_h_parent_err;
365
} else {
366
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2],
367
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
368
369
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]);
370
371
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2],
372
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
373
374
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]);
375
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H],
376
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
377
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
378
}
379
380
return 0;
381
382
clk_ck_mux_audio_h_parent_err:
383
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
384
clk_ck_mux_audio_h_err:
385
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2],
386
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
387
clk_ck_mux_eng2_parent_err:
388
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]);
389
clk_ck_mux_eng2_err:
390
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2],
391
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
392
clk_ck_mux_aud2_parent_err:
393
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]);
394
395
return ret;
396
}
397
398
static int mt8189_afe_disable_apll(struct mtk_base_afe *afe)
399
{
400
struct mt8189_afe_private *afe_priv = afe->platform_priv;
401
int ret;
402
403
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
404
if (ret)
405
return ret;
406
407
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]);
408
if (ret)
409
goto clk_ck_mux_aud1_err;
410
411
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1],
412
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
413
if (ret)
414
goto clk_ck_mux_aud1_parent_err;
415
416
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]);
417
if (ret)
418
goto clk_ck_mux_aud2_err;
419
420
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2],
421
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
422
if (ret)
423
goto clk_ck_mux_aud2_parent_err;
424
425
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]);
426
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]);
427
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H],
428
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
429
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
430
431
return 0;
432
433
clk_ck_mux_aud2_parent_err:
434
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]);
435
clk_ck_mux_aud2_err:
436
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1],
437
afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]);
438
clk_ck_mux_aud1_parent_err:
439
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]);
440
clk_ck_mux_aud1_err:
441
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
442
443
return ret;
444
}
445
446
int mt8189_apll1_enable(struct mtk_base_afe *afe)
447
{
448
int ret;
449
450
/* setting for APLL */
451
ret = apll1_mux_setting(afe, true);
452
if (ret)
453
return ret;
454
455
ret = mt8189_afe_enable_top_cg(afe, MT8189_CG_APLL1_CK);
456
if (ret)
457
return ret;
458
459
ret = mt8189_afe_enable_top_cg(afe, MT8189_PDN_APLL_TUNER1);
460
if (ret)
461
return ret;
462
463
/* sel 44.1kHz:1, apll_div:7, upper bound:3 */
464
regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG,
465
XTAL_EN_128FS_SEL_MASK_SFT | APLL_DIV_MASK_SFT |
466
UPPER_BOUND_MASK_SFT,
467
(0x1 << XTAL_EN_128FS_SEL_SFT) | (7 << APLL_DIV_SFT) |
468
(3 << UPPER_BOUND_SFT));
469
470
/* apll1 freq tuner enable */
471
regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG,
472
FREQ_TUNER_EN_MASK_SFT,
473
0x1 << FREQ_TUNER_EN_SFT);
474
475
/* audio apll1 on */
476
ret = mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_APLL1_EN_ON);
477
if (ret)
478
return ret;
479
480
return 0;
481
}
482
483
void mt8189_apll1_disable(struct mtk_base_afe *afe)
484
{
485
/* audio apll1 off */
486
mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_APLL1_EN_ON);
487
488
/* apll1 freq tuner disable */
489
regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG,
490
FREQ_TUNER_EN_MASK_SFT,
491
0x0);
492
493
mt8189_afe_disable_top_cg(afe, MT8189_PDN_APLL_TUNER1);
494
mt8189_afe_disable_top_cg(afe, MT8189_CG_APLL1_CK);
495
apll1_mux_setting(afe, false);
496
}
497
498
int mt8189_apll2_enable(struct mtk_base_afe *afe)
499
{
500
int ret;
501
502
/* setting for APLL */
503
ret = apll2_mux_setting(afe, true);
504
if (ret)
505
return ret;
506
507
ret = mt8189_afe_enable_top_cg(afe, MT8189_CG_APLL2_CK);
508
if (ret)
509
return ret;
510
511
ret = mt8189_afe_enable_top_cg(afe, MT8189_PDN_APLL_TUNER2);
512
if (ret)
513
return ret;
514
515
/* sel 48kHz: 2, apll_div: 7, upper bound: 3*/
516
regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG,
517
XTAL_EN_128FS_SEL_MASK_SFT | APLL_DIV_MASK_SFT |
518
UPPER_BOUND_MASK_SFT,
519
(0x2 << XTAL_EN_128FS_SEL_SFT) | (7 << APLL_DIV_SFT) |
520
(3 << UPPER_BOUND_SFT));
521
522
/* apll2 freq tuner enable */
523
regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG,
524
FREQ_TUNER_EN_MASK_SFT,
525
0x1 << FREQ_TUNER_EN_SFT);
526
527
/* audio apll2 on */
528
ret = mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_APLL2_EN_ON);
529
if (ret)
530
return ret;
531
532
return 0;
533
}
534
535
void mt8189_apll2_disable(struct mtk_base_afe *afe)
536
{
537
/* audio apll2 off */
538
mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_APLL2_EN_ON);
539
540
/* apll2 freq tuner disable */
541
regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG,
542
FREQ_TUNER_EN_MASK_SFT,
543
0x0);
544
545
mt8189_afe_disable_top_cg(afe, MT8189_PDN_APLL_TUNER2);
546
mt8189_afe_disable_top_cg(afe, MT8189_CG_APLL2_CK);
547
apll2_mux_setting(afe, false);
548
}
549
550
int mt8189_get_apll_rate(struct mtk_base_afe *afe, int apll)
551
{
552
struct mt8189_afe_private *afe_priv = afe->platform_priv;
553
int clk_id;
554
555
if (apll < MT8189_APLL1 || apll > MT8189_APLL2) {
556
dev_warn(afe->dev, "invalid clk id %d\n", apll);
557
return 0;
558
}
559
560
if (apll == MT8189_APLL1)
561
clk_id = MT8189_CLK_TOP_APLL1_CK;
562
else
563
clk_id = MT8189_CLK_TOP_APLL2_CK;
564
565
return clk_get_rate(afe_priv->clk[clk_id]);
566
}
567
568
int mt8189_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
569
{
570
return (rate % 8000) ? MT8189_APLL1 : MT8189_APLL2;
571
}
572
573
int mt8189_get_apll_by_name(struct mtk_base_afe *afe, const char *name)
574
{
575
if (strcmp(name, APLL1_W_NAME) == 0)
576
return MT8189_APLL1;
577
578
return MT8189_APLL2;
579
}
580
581
int mt8189_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate)
582
{
583
struct mt8189_afe_private *afe_priv = afe->platform_priv;
584
int apll = mt8189_get_apll_by_rate(afe, rate);
585
int apll_clk_id = apll == MT8189_APLL1 ?
586
MT8189_CLK_TOP_MUX_AUD_1 : MT8189_CLK_TOP_MUX_AUD_2;
587
int m_sel_id;
588
int div_clk_id;
589
int ret;
590
591
dev_dbg(afe->dev, "mck_id: %d, rate: %d\n", mck_id, rate);
592
593
if (mck_id >= MT8189_MCK_NUM || mck_id < 0)
594
return -EINVAL;
595
596
m_sel_id = mck_div[mck_id].m_sel_id;
597
div_clk_id = mck_div[mck_id].div_clk_id;
598
599
/* select apll */
600
if (m_sel_id >= 0) {
601
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[m_sel_id]);
602
if (ret)
603
return ret;
604
605
ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[m_sel_id],
606
afe_priv->clk[apll_clk_id]);
607
if (ret)
608
return ret;
609
}
610
611
/* enable div, set rate */
612
if (div_clk_id < 0) {
613
dev_err(afe->dev, "invalid div_clk_id %d\n", div_clk_id);
614
return -EINVAL;
615
}
616
617
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[div_clk_id]);
618
if (ret)
619
return ret;
620
621
ret = mt8189_afe_set_clk_rate(afe, afe_priv->clk[div_clk_id], rate);
622
if (ret)
623
return ret;
624
625
return 0;
626
}
627
628
int mt8189_mck_disable(struct mtk_base_afe *afe, int mck_id)
629
{
630
struct mt8189_afe_private *afe_priv = afe->platform_priv;
631
int m_sel_id;
632
int div_clk_id;
633
634
dev_dbg(afe->dev, "mck_id: %d.\n", mck_id);
635
636
if (mck_id < 0) {
637
dev_err(afe->dev, "mck_id = %d < 0\n", mck_id);
638
return -EINVAL;
639
}
640
641
m_sel_id = mck_div[mck_id].m_sel_id;
642
div_clk_id = mck_div[mck_id].div_clk_id;
643
644
if (div_clk_id < 0) {
645
dev_err(afe->dev, "div_clk_id = %d < 0\n",
646
div_clk_id);
647
return -EINVAL;
648
}
649
650
mt8189_afe_disable_clk(afe, afe_priv->clk[div_clk_id]);
651
652
if (m_sel_id >= 0)
653
mt8189_afe_disable_clk(afe, afe_priv->clk[m_sel_id]);
654
655
return 0;
656
}
657
658
int mt8189_afe_enable_reg_rw_clk(struct mtk_base_afe *afe)
659
{
660
struct mt8189_afe_private *afe_priv = afe->platform_priv;
661
662
/* bus clock for AFE internal access, like AFE SRAM */
663
mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS]);
664
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS],
665
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
666
/* enable audio clock source */
667
mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
668
mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H],
669
afe_priv->clk[MT8189_CLK_TOP_CLK26M]);
670
671
return 0;
672
}
673
674
int mt8189_afe_disable_reg_rw_clk(struct mtk_base_afe *afe)
675
{
676
struct mt8189_afe_private *afe_priv = afe->platform_priv;
677
678
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
679
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS]);
680
681
return 0;
682
}
683
684
int mt8189_afe_enable_main_clock(struct mtk_base_afe *afe)
685
{
686
return mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_26M_EN_ON);
687
}
688
689
void mt8189_afe_disable_main_clock(struct mtk_base_afe *afe)
690
{
691
mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_26M_EN_ON);
692
}
693
694
static int mt8189_afe_enable_ao_clock(struct mtk_base_afe *afe)
695
{
696
struct mt8189_afe_private *afe_priv = afe->platform_priv;
697
int ret;
698
699
/* Peri clock AO enable */
700
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_INTBUS_CK_PERI]);
701
if (ret)
702
return ret;
703
704
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI]);
705
if (ret)
706
goto err_clk_perao_slv;
707
708
ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_MST_CK_PERI]);
709
if (ret)
710
goto err_clk_perao_mst;
711
712
return 0;
713
714
err_clk_perao_mst:
715
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI]);
716
err_clk_perao_slv:
717
mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_INTBUS_CK_PERI]);
718
719
return ret;
720
}
721
722
int mt8189_init_clock(struct mtk_base_afe *afe)
723
{
724
struct mt8189_afe_private *afe_priv = afe->platform_priv;
725
int ret;
726
int i;
727
728
afe_priv->clk = devm_kcalloc(afe->dev, MT8189_CLK_NUM, sizeof(*afe_priv->clk),
729
GFP_KERNEL);
730
if (!afe_priv->clk)
731
return -ENOMEM;
732
733
for (i = 0; i < MT8189_CLK_NUM; i++) {
734
afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
735
if (IS_ERR(afe_priv->clk[i])) {
736
dev_err(afe->dev, "devm_clk_get %s fail\n", aud_clks[i]);
737
return PTR_ERR(afe_priv->clk[i]);
738
}
739
}
740
741
ret = mt8189_afe_disable_apll(afe);
742
if (ret)
743
return ret;
744
745
ret = mt8189_afe_enable_ao_clock(afe);
746
if (ret)
747
return ret;
748
749
return 0;
750
}
751
752