Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/mediatek/mt8365/mt8365-afe-clk.c
26488 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* MediaTek 8365 AFE clock control
4
*
5
* Copyright (c) 2024 MediaTek Inc.
6
* Authors: Jia Zeng <[email protected]>
7
* Alexandre Mergnat <[email protected]>
8
*/
9
10
#include "mt8365-afe-clk.h"
11
#include "mt8365-afe-common.h"
12
#include "mt8365-reg.h"
13
#include "../common/mtk-base-afe.h"
14
#include <linux/device.h>
15
#include <linux/mfd/syscon.h>
16
17
static const char *aud_clks[MT8365_CLK_NUM] = {
18
[MT8365_CLK_TOP_AUD_SEL] = "top_audio_sel",
19
[MT8365_CLK_AUD_I2S0_M] = "audio_i2s0_m",
20
[MT8365_CLK_AUD_I2S1_M] = "audio_i2s1_m",
21
[MT8365_CLK_AUD_I2S2_M] = "audio_i2s2_m",
22
[MT8365_CLK_AUD_I2S3_M] = "audio_i2s3_m",
23
[MT8365_CLK_ENGEN1] = "engen1",
24
[MT8365_CLK_ENGEN2] = "engen2",
25
[MT8365_CLK_AUD1] = "aud1",
26
[MT8365_CLK_AUD2] = "aud2",
27
[MT8365_CLK_I2S0_M_SEL] = "i2s0_m_sel",
28
[MT8365_CLK_I2S1_M_SEL] = "i2s1_m_sel",
29
[MT8365_CLK_I2S2_M_SEL] = "i2s2_m_sel",
30
[MT8365_CLK_I2S3_M_SEL] = "i2s3_m_sel",
31
[MT8365_CLK_CLK26M] = "top_clk26m_clk",
32
};
33
34
int mt8365_afe_init_audio_clk(struct mtk_base_afe *afe)
35
{
36
size_t i;
37
struct mt8365_afe_private *afe_priv = afe->platform_priv;
38
39
for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
40
afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
41
if (IS_ERR(afe_priv->clocks[i])) {
42
dev_err(afe->dev, "%s devm_clk_get %s fail\n",
43
__func__, aud_clks[i]);
44
return PTR_ERR(afe_priv->clocks[i]);
45
}
46
}
47
return 0;
48
}
49
50
void mt8365_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk)
51
{
52
clk_disable_unprepare(clk);
53
}
54
55
int mt8365_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
56
unsigned int rate)
57
{
58
int ret;
59
60
if (clk) {
61
ret = clk_set_rate(clk, rate);
62
if (ret) {
63
dev_err(afe->dev, "Failed to set rate\n");
64
return ret;
65
}
66
}
67
return 0;
68
}
69
70
int mt8365_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
71
struct clk *parent)
72
{
73
int ret;
74
75
if (clk && parent) {
76
ret = clk_set_parent(clk, parent);
77
if (ret) {
78
dev_err(afe->dev, "Failed to set parent\n");
79
return ret;
80
}
81
}
82
return 0;
83
}
84
85
static unsigned int get_top_cg_reg(unsigned int cg_type)
86
{
87
switch (cg_type) {
88
case MT8365_TOP_CG_AFE:
89
case MT8365_TOP_CG_I2S_IN:
90
case MT8365_TOP_CG_22M:
91
case MT8365_TOP_CG_24M:
92
case MT8365_TOP_CG_INTDIR_CK:
93
case MT8365_TOP_CG_APLL2_TUNER:
94
case MT8365_TOP_CG_APLL_TUNER:
95
case MT8365_TOP_CG_SPDIF:
96
case MT8365_TOP_CG_TDM_OUT:
97
case MT8365_TOP_CG_TDM_IN:
98
case MT8365_TOP_CG_ADC:
99
case MT8365_TOP_CG_DAC:
100
case MT8365_TOP_CG_DAC_PREDIS:
101
case MT8365_TOP_CG_TML:
102
return AUDIO_TOP_CON0;
103
case MT8365_TOP_CG_I2S1_BCLK:
104
case MT8365_TOP_CG_I2S2_BCLK:
105
case MT8365_TOP_CG_I2S3_BCLK:
106
case MT8365_TOP_CG_I2S4_BCLK:
107
case MT8365_TOP_CG_DMIC0_ADC:
108
case MT8365_TOP_CG_DMIC1_ADC:
109
case MT8365_TOP_CG_DMIC2_ADC:
110
case MT8365_TOP_CG_DMIC3_ADC:
111
case MT8365_TOP_CG_CONNSYS_I2S_ASRC:
112
case MT8365_TOP_CG_GENERAL1_ASRC:
113
case MT8365_TOP_CG_GENERAL2_ASRC:
114
case MT8365_TOP_CG_TDM_ASRC:
115
return AUDIO_TOP_CON1;
116
default:
117
return 0;
118
}
119
}
120
121
static unsigned int get_top_cg_mask(unsigned int cg_type)
122
{
123
switch (cg_type) {
124
case MT8365_TOP_CG_AFE:
125
return AUD_TCON0_PDN_AFE;
126
case MT8365_TOP_CG_I2S_IN:
127
return AUD_TCON0_PDN_I2S_IN;
128
case MT8365_TOP_CG_22M:
129
return AUD_TCON0_PDN_22M;
130
case MT8365_TOP_CG_24M:
131
return AUD_TCON0_PDN_24M;
132
case MT8365_TOP_CG_INTDIR_CK:
133
return AUD_TCON0_PDN_INTDIR;
134
case MT8365_TOP_CG_APLL2_TUNER:
135
return AUD_TCON0_PDN_APLL2_TUNER;
136
case MT8365_TOP_CG_APLL_TUNER:
137
return AUD_TCON0_PDN_APLL_TUNER;
138
case MT8365_TOP_CG_SPDIF:
139
return AUD_TCON0_PDN_SPDIF;
140
case MT8365_TOP_CG_TDM_OUT:
141
return AUD_TCON0_PDN_TDM_OUT;
142
case MT8365_TOP_CG_TDM_IN:
143
return AUD_TCON0_PDN_TDM_IN;
144
case MT8365_TOP_CG_ADC:
145
return AUD_TCON0_PDN_ADC;
146
case MT8365_TOP_CG_DAC:
147
return AUD_TCON0_PDN_DAC;
148
case MT8365_TOP_CG_DAC_PREDIS:
149
return AUD_TCON0_PDN_DAC_PREDIS;
150
case MT8365_TOP_CG_TML:
151
return AUD_TCON0_PDN_TML;
152
case MT8365_TOP_CG_I2S1_BCLK:
153
return AUD_TCON1_PDN_I2S1_BCLK;
154
case MT8365_TOP_CG_I2S2_BCLK:
155
return AUD_TCON1_PDN_I2S2_BCLK;
156
case MT8365_TOP_CG_I2S3_BCLK:
157
return AUD_TCON1_PDN_I2S3_BCLK;
158
case MT8365_TOP_CG_I2S4_BCLK:
159
return AUD_TCON1_PDN_I2S4_BCLK;
160
case MT8365_TOP_CG_DMIC0_ADC:
161
return AUD_TCON1_PDN_DMIC0_ADC;
162
case MT8365_TOP_CG_DMIC1_ADC:
163
return AUD_TCON1_PDN_DMIC1_ADC;
164
case MT8365_TOP_CG_DMIC2_ADC:
165
return AUD_TCON1_PDN_DMIC2_ADC;
166
case MT8365_TOP_CG_DMIC3_ADC:
167
return AUD_TCON1_PDN_DMIC3_ADC;
168
case MT8365_TOP_CG_CONNSYS_I2S_ASRC:
169
return AUD_TCON1_PDN_CONNSYS_I2S_ASRC;
170
case MT8365_TOP_CG_GENERAL1_ASRC:
171
return AUD_TCON1_PDN_GENERAL1_ASRC;
172
case MT8365_TOP_CG_GENERAL2_ASRC:
173
return AUD_TCON1_PDN_GENERAL2_ASRC;
174
case MT8365_TOP_CG_TDM_ASRC:
175
return AUD_TCON1_PDN_TDM_ASRC;
176
default:
177
return 0;
178
}
179
}
180
181
static unsigned int get_top_cg_on_val(unsigned int cg_type)
182
{
183
return 0;
184
}
185
186
static unsigned int get_top_cg_off_val(unsigned int cg_type)
187
{
188
return get_top_cg_mask(cg_type);
189
}
190
191
int mt8365_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
192
{
193
struct mt8365_afe_private *afe_priv = afe->platform_priv;
194
unsigned int reg = get_top_cg_reg(cg_type);
195
unsigned int mask = get_top_cg_mask(cg_type);
196
unsigned int val = get_top_cg_on_val(cg_type);
197
unsigned long flags;
198
199
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
200
201
afe_priv->top_cg_ref_cnt[cg_type]++;
202
if (afe_priv->top_cg_ref_cnt[cg_type] == 1)
203
regmap_update_bits(afe->regmap, reg, mask, val);
204
205
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
206
207
return 0;
208
}
209
210
int mt8365_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
211
{
212
struct mt8365_afe_private *afe_priv = afe->platform_priv;
213
unsigned int reg = get_top_cg_reg(cg_type);
214
unsigned int mask = get_top_cg_mask(cg_type);
215
unsigned int val = get_top_cg_off_val(cg_type);
216
unsigned long flags;
217
218
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
219
220
afe_priv->top_cg_ref_cnt[cg_type]--;
221
if (afe_priv->top_cg_ref_cnt[cg_type] == 0)
222
regmap_update_bits(afe->regmap, reg, mask, val);
223
else if (afe_priv->top_cg_ref_cnt[cg_type] < 0)
224
afe_priv->top_cg_ref_cnt[cg_type] = 0;
225
226
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
227
228
return 0;
229
}
230
231
int mt8365_afe_enable_main_clk(struct mtk_base_afe *afe)
232
{
233
struct mt8365_afe_private *afe_priv = afe->platform_priv;
234
235
clk_prepare_enable(afe_priv->clocks[MT8365_CLK_TOP_AUD_SEL]);
236
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_AFE);
237
mt8365_afe_enable_afe_on(afe);
238
239
return 0;
240
}
241
242
int mt8365_afe_disable_main_clk(struct mtk_base_afe *afe)
243
{
244
struct mt8365_afe_private *afe_priv = afe->platform_priv;
245
246
mt8365_afe_disable_afe_on(afe);
247
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_AFE);
248
mt8365_afe_disable_clk(afe, afe_priv->clocks[MT8365_CLK_TOP_AUD_SEL]);
249
250
return 0;
251
}
252
253
int mt8365_afe_emi_clk_on(struct mtk_base_afe *afe)
254
{
255
return 0;
256
}
257
258
int mt8365_afe_emi_clk_off(struct mtk_base_afe *afe)
259
{
260
return 0;
261
}
262
263
int mt8365_afe_enable_afe_on(struct mtk_base_afe *afe)
264
{
265
struct mt8365_afe_private *afe_priv = afe->platform_priv;
266
unsigned long flags;
267
268
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
269
270
afe_priv->afe_on_ref_cnt++;
271
if (afe_priv->afe_on_ref_cnt == 1)
272
regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
273
274
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
275
276
return 0;
277
}
278
279
int mt8365_afe_disable_afe_on(struct mtk_base_afe *afe)
280
{
281
struct mt8365_afe_private *afe_priv = afe->platform_priv;
282
unsigned long flags;
283
284
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
285
286
afe_priv->afe_on_ref_cnt--;
287
if (afe_priv->afe_on_ref_cnt == 0)
288
regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0);
289
else if (afe_priv->afe_on_ref_cnt < 0)
290
afe_priv->afe_on_ref_cnt = 0;
291
292
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
293
294
return 0;
295
}
296
297
static int mt8365_afe_hd_engen_enable(struct mtk_base_afe *afe, bool apll1)
298
{
299
if (apll1)
300
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
301
AFE_22M_PLL_EN, AFE_22M_PLL_EN);
302
else
303
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
304
AFE_24M_PLL_EN, AFE_24M_PLL_EN);
305
306
return 0;
307
}
308
309
static int mt8365_afe_hd_engen_disable(struct mtk_base_afe *afe, bool apll1)
310
{
311
if (apll1)
312
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
313
AFE_22M_PLL_EN, ~AFE_22M_PLL_EN);
314
else
315
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
316
AFE_24M_PLL_EN, ~AFE_24M_PLL_EN);
317
318
return 0;
319
}
320
321
int mt8365_afe_enable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll)
322
{
323
struct mt8365_afe_private *afe_priv = afe->platform_priv;
324
325
mutex_lock(&afe_priv->afe_clk_mutex);
326
327
afe_priv->apll_tuner_ref_cnt[apll]++;
328
if (afe_priv->apll_tuner_ref_cnt[apll] != 1) {
329
mutex_unlock(&afe_priv->afe_clk_mutex);
330
return 0;
331
}
332
333
if (apll == MT8365_AFE_APLL1) {
334
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG,
335
AFE_APLL_TUNER_CFG_MASK, 0x432);
336
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG,
337
AFE_APLL_TUNER_CFG_EN_MASK, 0x1);
338
} else {
339
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1,
340
AFE_APLL_TUNER_CFG1_MASK, 0x434);
341
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1,
342
AFE_APLL_TUNER_CFG1_EN_MASK, 0x1);
343
}
344
345
mutex_unlock(&afe_priv->afe_clk_mutex);
346
return 0;
347
}
348
349
int mt8365_afe_disable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll)
350
{
351
struct mt8365_afe_private *afe_priv = afe->platform_priv;
352
353
mutex_lock(&afe_priv->afe_clk_mutex);
354
355
afe_priv->apll_tuner_ref_cnt[apll]--;
356
if (afe_priv->apll_tuner_ref_cnt[apll] == 0) {
357
if (apll == MT8365_AFE_APLL1)
358
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG,
359
AFE_APLL_TUNER_CFG_EN_MASK, 0x0);
360
else
361
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1,
362
AFE_APLL_TUNER_CFG1_EN_MASK, 0x0);
363
364
} else if (afe_priv->apll_tuner_ref_cnt[apll] < 0) {
365
afe_priv->apll_tuner_ref_cnt[apll] = 0;
366
}
367
368
mutex_unlock(&afe_priv->afe_clk_mutex);
369
return 0;
370
}
371
372
int mt8365_afe_enable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll)
373
{
374
struct mt8365_afe_private *afe_priv = afe->platform_priv;
375
376
if (apll == MT8365_AFE_APLL1) {
377
if (clk_prepare_enable(afe_priv->clocks[MT8365_CLK_ENGEN1])) {
378
dev_info(afe->dev, "%s Failed to enable ENGEN1 clk\n",
379
__func__);
380
return 0;
381
}
382
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_22M);
383
mt8365_afe_hd_engen_enable(afe, true);
384
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_APLL_TUNER);
385
mt8365_afe_enable_apll_tuner_cfg(afe, MT8365_AFE_APLL1);
386
} else {
387
if (clk_prepare_enable(afe_priv->clocks[MT8365_CLK_ENGEN2])) {
388
dev_info(afe->dev, "%s Failed to enable ENGEN2 clk\n",
389
__func__);
390
return 0;
391
}
392
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_24M);
393
mt8365_afe_hd_engen_enable(afe, false);
394
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_APLL2_TUNER);
395
mt8365_afe_enable_apll_tuner_cfg(afe, MT8365_AFE_APLL2);
396
}
397
398
return 0;
399
}
400
401
int mt8365_afe_disable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll)
402
{
403
struct mt8365_afe_private *afe_priv = afe->platform_priv;
404
405
if (apll == MT8365_AFE_APLL1) {
406
mt8365_afe_disable_apll_tuner_cfg(afe, MT8365_AFE_APLL1);
407
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_APLL_TUNER);
408
mt8365_afe_hd_engen_disable(afe, true);
409
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_22M);
410
clk_disable_unprepare(afe_priv->clocks[MT8365_CLK_ENGEN1]);
411
} else {
412
mt8365_afe_disable_apll_tuner_cfg(afe, MT8365_AFE_APLL2);
413
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_APLL2_TUNER);
414
mt8365_afe_hd_engen_disable(afe, false);
415
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_24M);
416
clk_disable_unprepare(afe_priv->clocks[MT8365_CLK_ENGEN2]);
417
}
418
419
return 0;
420
}
421
422