File Index
Files and directories
Sign in
FILE

mt8189-afe-clk.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/mediatek/mt8189/mt8189-afe-clk.c C
  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 <darren.ye@mediatek.com>
  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 */
 17struct mt8189_mck_div {
 18	int m_sel_id;
 19	int div_clk_id;
 20};
 21
 22static 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
 53static 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
 88int 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}
100EXPORT_SYMBOL_GPL(mt8189_afe_enable_clk);
101
102void 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}
109EXPORT_SYMBOL_GPL(mt8189_afe_disable_clk);
110
111static 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
127static 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
143static 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
163static 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
191static 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
211static 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
231static 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
247static 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
262static 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
314clk_ck_mux_audio_h_parent_err:
315	mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
316clk_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]);
319clk_ck_mux_eng1_parent_err:
320	mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]);
321clk_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]);
324clk_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
330static 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
382clk_ck_mux_audio_h_parent_err:
383	mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]);
384clk_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]);
387clk_ck_mux_eng2_parent_err:
388	mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]);
389clk_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]);
392clk_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
398static 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
433clk_ck_mux_aud2_parent_err:
434	mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]);
435clk_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]);
438clk_ck_mux_aud1_parent_err:
439	mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]);
440clk_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
446int 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
483void 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
498int 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
535void 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
550int 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
568int mt8189_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
569{
570	return (rate % 8000) ? MT8189_APLL1 : MT8189_APLL2;
571}
572
573int 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
581int 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
628int 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
658int 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
674int 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
684int 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
689void 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
694static 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
714err_clk_perao_mst:
715	mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI]);
716err_clk_perao_slv:
717	mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_INTBUS_CK_PERI]);
718
719	return ret;
720}
721
722int 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}
~/ Read-only file preview.