1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // mt8183-afe-clk.c -- Mediatek 8183 afe clock ctrl
4*4882a593Smuzhiyun //
5*4882a593Smuzhiyun // Copyright (c) 2018 MediaTek Inc.
6*4882a593Smuzhiyun // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/clk.h>
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include "mt8183-afe-common.h"
11*4882a593Smuzhiyun #include "mt8183-afe-clk.h"
12*4882a593Smuzhiyun #include "mt8183-reg.h"
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun enum {
15*4882a593Smuzhiyun CLK_AFE = 0,
16*4882a593Smuzhiyun CLK_TML,
17*4882a593Smuzhiyun CLK_APLL22M,
18*4882a593Smuzhiyun CLK_APLL24M,
19*4882a593Smuzhiyun CLK_APLL1_TUNER,
20*4882a593Smuzhiyun CLK_APLL2_TUNER,
21*4882a593Smuzhiyun CLK_I2S1_BCLK_SW,
22*4882a593Smuzhiyun CLK_I2S2_BCLK_SW,
23*4882a593Smuzhiyun CLK_I2S3_BCLK_SW,
24*4882a593Smuzhiyun CLK_I2S4_BCLK_SW,
25*4882a593Smuzhiyun CLK_INFRA_SYS_AUDIO,
26*4882a593Smuzhiyun CLK_MUX_AUDIO,
27*4882a593Smuzhiyun CLK_MUX_AUDIOINTBUS,
28*4882a593Smuzhiyun CLK_TOP_SYSPLL_D2_D4,
29*4882a593Smuzhiyun /* apll related mux */
30*4882a593Smuzhiyun CLK_TOP_MUX_AUD_1,
31*4882a593Smuzhiyun CLK_TOP_APLL1_CK,
32*4882a593Smuzhiyun CLK_TOP_MUX_AUD_2,
33*4882a593Smuzhiyun CLK_TOP_APLL2_CK,
34*4882a593Smuzhiyun CLK_TOP_MUX_AUD_ENG1,
35*4882a593Smuzhiyun CLK_TOP_APLL1_D8,
36*4882a593Smuzhiyun CLK_TOP_MUX_AUD_ENG2,
37*4882a593Smuzhiyun CLK_TOP_APLL2_D8,
38*4882a593Smuzhiyun CLK_TOP_I2S0_M_SEL,
39*4882a593Smuzhiyun CLK_TOP_I2S1_M_SEL,
40*4882a593Smuzhiyun CLK_TOP_I2S2_M_SEL,
41*4882a593Smuzhiyun CLK_TOP_I2S3_M_SEL,
42*4882a593Smuzhiyun CLK_TOP_I2S4_M_SEL,
43*4882a593Smuzhiyun CLK_TOP_I2S5_M_SEL,
44*4882a593Smuzhiyun CLK_TOP_APLL12_DIV0,
45*4882a593Smuzhiyun CLK_TOP_APLL12_DIV1,
46*4882a593Smuzhiyun CLK_TOP_APLL12_DIV2,
47*4882a593Smuzhiyun CLK_TOP_APLL12_DIV3,
48*4882a593Smuzhiyun CLK_TOP_APLL12_DIV4,
49*4882a593Smuzhiyun CLK_TOP_APLL12_DIVB,
50*4882a593Smuzhiyun CLK_CLK26M,
51*4882a593Smuzhiyun CLK_NUM
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun static const char *aud_clks[CLK_NUM] = {
55*4882a593Smuzhiyun [CLK_AFE] = "aud_afe_clk",
56*4882a593Smuzhiyun [CLK_TML] = "aud_tml_clk",
57*4882a593Smuzhiyun [CLK_APLL22M] = "aud_apll22m_clk",
58*4882a593Smuzhiyun [CLK_APLL24M] = "aud_apll24m_clk",
59*4882a593Smuzhiyun [CLK_APLL1_TUNER] = "aud_apll1_tuner_clk",
60*4882a593Smuzhiyun [CLK_APLL2_TUNER] = "aud_apll2_tuner_clk",
61*4882a593Smuzhiyun [CLK_I2S1_BCLK_SW] = "aud_i2s1_bclk_sw",
62*4882a593Smuzhiyun [CLK_I2S2_BCLK_SW] = "aud_i2s2_bclk_sw",
63*4882a593Smuzhiyun [CLK_I2S3_BCLK_SW] = "aud_i2s3_bclk_sw",
64*4882a593Smuzhiyun [CLK_I2S4_BCLK_SW] = "aud_i2s4_bclk_sw",
65*4882a593Smuzhiyun [CLK_INFRA_SYS_AUDIO] = "aud_infra_clk",
66*4882a593Smuzhiyun [CLK_MUX_AUDIO] = "top_mux_audio",
67*4882a593Smuzhiyun [CLK_MUX_AUDIOINTBUS] = "top_mux_aud_intbus",
68*4882a593Smuzhiyun [CLK_TOP_SYSPLL_D2_D4] = "top_syspll_d2_d4",
69*4882a593Smuzhiyun [CLK_TOP_MUX_AUD_1] = "top_mux_aud_1",
70*4882a593Smuzhiyun [CLK_TOP_APLL1_CK] = "top_apll1_ck",
71*4882a593Smuzhiyun [CLK_TOP_MUX_AUD_2] = "top_mux_aud_2",
72*4882a593Smuzhiyun [CLK_TOP_APLL2_CK] = "top_apll2_ck",
73*4882a593Smuzhiyun [CLK_TOP_MUX_AUD_ENG1] = "top_mux_aud_eng1",
74*4882a593Smuzhiyun [CLK_TOP_APLL1_D8] = "top_apll1_d8",
75*4882a593Smuzhiyun [CLK_TOP_MUX_AUD_ENG2] = "top_mux_aud_eng2",
76*4882a593Smuzhiyun [CLK_TOP_APLL2_D8] = "top_apll2_d8",
77*4882a593Smuzhiyun [CLK_TOP_I2S0_M_SEL] = "top_i2s0_m_sel",
78*4882a593Smuzhiyun [CLK_TOP_I2S1_M_SEL] = "top_i2s1_m_sel",
79*4882a593Smuzhiyun [CLK_TOP_I2S2_M_SEL] = "top_i2s2_m_sel",
80*4882a593Smuzhiyun [CLK_TOP_I2S3_M_SEL] = "top_i2s3_m_sel",
81*4882a593Smuzhiyun [CLK_TOP_I2S4_M_SEL] = "top_i2s4_m_sel",
82*4882a593Smuzhiyun [CLK_TOP_I2S5_M_SEL] = "top_i2s5_m_sel",
83*4882a593Smuzhiyun [CLK_TOP_APLL12_DIV0] = "top_apll12_div0",
84*4882a593Smuzhiyun [CLK_TOP_APLL12_DIV1] = "top_apll12_div1",
85*4882a593Smuzhiyun [CLK_TOP_APLL12_DIV2] = "top_apll12_div2",
86*4882a593Smuzhiyun [CLK_TOP_APLL12_DIV3] = "top_apll12_div3",
87*4882a593Smuzhiyun [CLK_TOP_APLL12_DIV4] = "top_apll12_div4",
88*4882a593Smuzhiyun [CLK_TOP_APLL12_DIVB] = "top_apll12_divb",
89*4882a593Smuzhiyun [CLK_CLK26M] = "top_clk26m_clk",
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun
mt8183_init_clock(struct mtk_base_afe * afe)92*4882a593Smuzhiyun int mt8183_init_clock(struct mtk_base_afe *afe)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
95*4882a593Smuzhiyun int i;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),
98*4882a593Smuzhiyun GFP_KERNEL);
99*4882a593Smuzhiyun if (!afe_priv->clk)
100*4882a593Smuzhiyun return -ENOMEM;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun for (i = 0; i < CLK_NUM; i++) {
103*4882a593Smuzhiyun afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
104*4882a593Smuzhiyun if (IS_ERR(afe_priv->clk[i])) {
105*4882a593Smuzhiyun dev_err(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",
106*4882a593Smuzhiyun __func__, aud_clks[i],
107*4882a593Smuzhiyun PTR_ERR(afe_priv->clk[i]));
108*4882a593Smuzhiyun return PTR_ERR(afe_priv->clk[i]);
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun return 0;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
mt8183_afe_enable_clock(struct mtk_base_afe * afe)115*4882a593Smuzhiyun int mt8183_afe_enable_clock(struct mtk_base_afe *afe)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
118*4882a593Smuzhiyun int ret;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
121*4882a593Smuzhiyun if (ret) {
122*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
123*4882a593Smuzhiyun __func__, aud_clks[CLK_INFRA_SYS_AUDIO], ret);
124*4882a593Smuzhiyun goto CLK_INFRA_SYS_AUDIO_ERR;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIO]);
128*4882a593Smuzhiyun if (ret) {
129*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
130*4882a593Smuzhiyun __func__, aud_clks[CLK_MUX_AUDIO], ret);
131*4882a593Smuzhiyun goto CLK_MUX_AUDIO_ERR;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIO],
135*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
136*4882a593Smuzhiyun if (ret) {
137*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
138*4882a593Smuzhiyun __func__, aud_clks[CLK_MUX_AUDIO],
139*4882a593Smuzhiyun aud_clks[CLK_CLK26M], ret);
140*4882a593Smuzhiyun goto CLK_MUX_AUDIO_ERR;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
144*4882a593Smuzhiyun if (ret) {
145*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
146*4882a593Smuzhiyun __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
147*4882a593Smuzhiyun goto CLK_MUX_AUDIO_INTBUS_ERR;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIOINTBUS],
151*4882a593Smuzhiyun afe_priv->clk[CLK_TOP_SYSPLL_D2_D4]);
152*4882a593Smuzhiyun if (ret) {
153*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
154*4882a593Smuzhiyun __func__, aud_clks[CLK_MUX_AUDIOINTBUS],
155*4882a593Smuzhiyun aud_clks[CLK_TOP_SYSPLL_D2_D4], ret);
156*4882a593Smuzhiyun goto CLK_MUX_AUDIO_INTBUS_ERR;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_AFE]);
160*4882a593Smuzhiyun if (ret) {
161*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
162*4882a593Smuzhiyun __func__, aud_clks[CLK_AFE], ret);
163*4882a593Smuzhiyun goto CLK_AFE_ERR;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_I2S1_BCLK_SW]);
167*4882a593Smuzhiyun if (ret) {
168*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
169*4882a593Smuzhiyun __func__, aud_clks[CLK_I2S1_BCLK_SW], ret);
170*4882a593Smuzhiyun goto CLK_I2S1_BCLK_SW_ERR;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_I2S2_BCLK_SW]);
174*4882a593Smuzhiyun if (ret) {
175*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
176*4882a593Smuzhiyun __func__, aud_clks[CLK_I2S2_BCLK_SW], ret);
177*4882a593Smuzhiyun goto CLK_I2S2_BCLK_SW_ERR;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_I2S3_BCLK_SW]);
181*4882a593Smuzhiyun if (ret) {
182*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
183*4882a593Smuzhiyun __func__, aud_clks[CLK_I2S3_BCLK_SW], ret);
184*4882a593Smuzhiyun goto CLK_I2S3_BCLK_SW_ERR;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_I2S4_BCLK_SW]);
188*4882a593Smuzhiyun if (ret) {
189*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
190*4882a593Smuzhiyun __func__, aud_clks[CLK_I2S4_BCLK_SW], ret);
191*4882a593Smuzhiyun goto CLK_I2S4_BCLK_SW_ERR;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun return 0;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun CLK_I2S4_BCLK_SW_ERR:
197*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_I2S3_BCLK_SW]);
198*4882a593Smuzhiyun CLK_I2S3_BCLK_SW_ERR:
199*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_I2S2_BCLK_SW]);
200*4882a593Smuzhiyun CLK_I2S2_BCLK_SW_ERR:
201*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_I2S1_BCLK_SW]);
202*4882a593Smuzhiyun CLK_I2S1_BCLK_SW_ERR:
203*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
204*4882a593Smuzhiyun CLK_AFE_ERR:
205*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
206*4882a593Smuzhiyun CLK_MUX_AUDIO_INTBUS_ERR:
207*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
208*4882a593Smuzhiyun CLK_MUX_AUDIO_ERR:
209*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
210*4882a593Smuzhiyun CLK_INFRA_SYS_AUDIO_ERR:
211*4882a593Smuzhiyun return ret;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
mt8183_afe_disable_clock(struct mtk_base_afe * afe)214*4882a593Smuzhiyun int mt8183_afe_disable_clock(struct mtk_base_afe *afe)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_I2S4_BCLK_SW]);
219*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_I2S3_BCLK_SW]);
220*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_I2S2_BCLK_SW]);
221*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_I2S1_BCLK_SW]);
222*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
223*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
224*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
225*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun return 0;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun /* apll */
apll1_mux_setting(struct mtk_base_afe * afe,bool enable)231*4882a593Smuzhiyun static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
234*4882a593Smuzhiyun int ret;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun if (enable) {
237*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_1]);
238*4882a593Smuzhiyun if (ret) {
239*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
240*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_1], ret);
241*4882a593Smuzhiyun goto ERR_ENABLE_CLK_TOP_MUX_AUD_1;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
244*4882a593Smuzhiyun afe_priv->clk[CLK_TOP_APLL1_CK]);
245*4882a593Smuzhiyun if (ret) {
246*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
247*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_1],
248*4882a593Smuzhiyun aud_clks[CLK_TOP_APLL1_CK], ret);
249*4882a593Smuzhiyun goto ERR_SELECT_CLK_TOP_MUX_AUD_1;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* 180.6336 / 8 = 22.5792MHz */
253*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);
254*4882a593Smuzhiyun if (ret) {
255*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
256*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1], ret);
257*4882a593Smuzhiyun goto ERR_ENABLE_CLK_TOP_MUX_AUD_ENG1;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],
260*4882a593Smuzhiyun afe_priv->clk[CLK_TOP_APLL1_D8]);
261*4882a593Smuzhiyun if (ret) {
262*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
263*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1],
264*4882a593Smuzhiyun aud_clks[CLK_TOP_APLL1_D8], ret);
265*4882a593Smuzhiyun goto ERR_SELECT_CLK_TOP_MUX_AUD_ENG1;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun } else {
268*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],
269*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
270*4882a593Smuzhiyun if (ret) {
271*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
272*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1],
273*4882a593Smuzhiyun aud_clks[CLK_CLK26M], ret);
274*4882a593Smuzhiyun goto EXIT;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
279*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
280*4882a593Smuzhiyun if (ret) {
281*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
282*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_1],
283*4882a593Smuzhiyun aud_clks[CLK_CLK26M], ret);
284*4882a593Smuzhiyun goto EXIT;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_1]);
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun return 0;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun ERR_SELECT_CLK_TOP_MUX_AUD_ENG1:
292*4882a593Smuzhiyun clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],
293*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
294*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);
295*4882a593Smuzhiyun ERR_ENABLE_CLK_TOP_MUX_AUD_ENG1:
296*4882a593Smuzhiyun ERR_SELECT_CLK_TOP_MUX_AUD_1:
297*4882a593Smuzhiyun clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
298*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
299*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_1]);
300*4882a593Smuzhiyun ERR_ENABLE_CLK_TOP_MUX_AUD_1:
301*4882a593Smuzhiyun EXIT:
302*4882a593Smuzhiyun return ret;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun
apll2_mux_setting(struct mtk_base_afe * afe,bool enable)305*4882a593Smuzhiyun static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
308*4882a593Smuzhiyun int ret;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun if (enable) {
311*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_2]);
312*4882a593Smuzhiyun if (ret) {
313*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
314*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_2], ret);
315*4882a593Smuzhiyun goto ERR_ENABLE_CLK_TOP_MUX_AUD_2;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
318*4882a593Smuzhiyun afe_priv->clk[CLK_TOP_APLL2_CK]);
319*4882a593Smuzhiyun if (ret) {
320*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
321*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_2],
322*4882a593Smuzhiyun aud_clks[CLK_TOP_APLL2_CK], ret);
323*4882a593Smuzhiyun goto ERR_SELECT_CLK_TOP_MUX_AUD_2;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun /* 196.608 / 8 = 24.576MHz */
327*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);
328*4882a593Smuzhiyun if (ret) {
329*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
330*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2], ret);
331*4882a593Smuzhiyun goto ERR_ENABLE_CLK_TOP_MUX_AUD_ENG2;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],
334*4882a593Smuzhiyun afe_priv->clk[CLK_TOP_APLL2_D8]);
335*4882a593Smuzhiyun if (ret) {
336*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
337*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2],
338*4882a593Smuzhiyun aud_clks[CLK_TOP_APLL2_D8], ret);
339*4882a593Smuzhiyun goto ERR_SELECT_CLK_TOP_MUX_AUD_ENG2;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun } else {
342*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],
343*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
344*4882a593Smuzhiyun if (ret) {
345*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
346*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2],
347*4882a593Smuzhiyun aud_clks[CLK_CLK26M], ret);
348*4882a593Smuzhiyun goto EXIT;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
353*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
354*4882a593Smuzhiyun if (ret) {
355*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
356*4882a593Smuzhiyun __func__, aud_clks[CLK_TOP_MUX_AUD_2],
357*4882a593Smuzhiyun aud_clks[CLK_CLK26M], ret);
358*4882a593Smuzhiyun goto EXIT;
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_2]);
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun return 0;
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun ERR_SELECT_CLK_TOP_MUX_AUD_ENG2:
366*4882a593Smuzhiyun clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],
367*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
368*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);
369*4882a593Smuzhiyun ERR_ENABLE_CLK_TOP_MUX_AUD_ENG2:
370*4882a593Smuzhiyun ERR_SELECT_CLK_TOP_MUX_AUD_2:
371*4882a593Smuzhiyun clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
372*4882a593Smuzhiyun afe_priv->clk[CLK_CLK26M]);
373*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_2]);
374*4882a593Smuzhiyun ERR_ENABLE_CLK_TOP_MUX_AUD_2:
375*4882a593Smuzhiyun EXIT:
376*4882a593Smuzhiyun return ret;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
mt8183_apll1_enable(struct mtk_base_afe * afe)379*4882a593Smuzhiyun int mt8183_apll1_enable(struct mtk_base_afe *afe)
380*4882a593Smuzhiyun {
381*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
382*4882a593Smuzhiyun int ret;
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /* setting for APLL */
385*4882a593Smuzhiyun apll1_mux_setting(afe, true);
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_APLL22M]);
388*4882a593Smuzhiyun if (ret) {
389*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
390*4882a593Smuzhiyun __func__, aud_clks[CLK_APLL22M], ret);
391*4882a593Smuzhiyun goto ERR_CLK_APLL22M;
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1_TUNER]);
395*4882a593Smuzhiyun if (ret) {
396*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
397*4882a593Smuzhiyun __func__, aud_clks[CLK_APLL1_TUNER], ret);
398*4882a593Smuzhiyun goto ERR_CLK_APLL1_TUNER;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG,
402*4882a593Smuzhiyun 0x0000FFF7, 0x00000832);
403*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x1);
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
406*4882a593Smuzhiyun AFE_22M_ON_MASK_SFT,
407*4882a593Smuzhiyun 0x1 << AFE_22M_ON_SFT);
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun return 0;
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun ERR_CLK_APLL1_TUNER:
412*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
413*4882a593Smuzhiyun ERR_CLK_APLL22M:
414*4882a593Smuzhiyun return ret;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
mt8183_apll1_disable(struct mtk_base_afe * afe)417*4882a593Smuzhiyun void mt8183_apll1_disable(struct mtk_base_afe *afe)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
422*4882a593Smuzhiyun AFE_22M_ON_MASK_SFT,
423*4882a593Smuzhiyun 0x0 << AFE_22M_ON_SFT);
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x0);
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);
428*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun apll1_mux_setting(afe, false);
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun
mt8183_apll2_enable(struct mtk_base_afe * afe)433*4882a593Smuzhiyun int mt8183_apll2_enable(struct mtk_base_afe *afe)
434*4882a593Smuzhiyun {
435*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
436*4882a593Smuzhiyun int ret;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun /* setting for APLL */
439*4882a593Smuzhiyun apll2_mux_setting(afe, true);
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_APLL24M]);
442*4882a593Smuzhiyun if (ret) {
443*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
444*4882a593Smuzhiyun __func__, aud_clks[CLK_APLL24M], ret);
445*4882a593Smuzhiyun goto ERR_CLK_APLL24M;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2_TUNER]);
449*4882a593Smuzhiyun if (ret) {
450*4882a593Smuzhiyun dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
451*4882a593Smuzhiyun __func__, aud_clks[CLK_APLL2_TUNER], ret);
452*4882a593Smuzhiyun goto ERR_CLK_APLL2_TUNER;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG,
456*4882a593Smuzhiyun 0x0000FFF7, 0x00000634);
457*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x1);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
460*4882a593Smuzhiyun AFE_24M_ON_MASK_SFT,
461*4882a593Smuzhiyun 0x1 << AFE_24M_ON_SFT);
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun return 0;
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun ERR_CLK_APLL2_TUNER:
466*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
467*4882a593Smuzhiyun ERR_CLK_APLL24M:
468*4882a593Smuzhiyun return ret;
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
mt8183_apll2_disable(struct mtk_base_afe * afe)471*4882a593Smuzhiyun void mt8183_apll2_disable(struct mtk_base_afe *afe)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
476*4882a593Smuzhiyun AFE_24M_ON_MASK_SFT,
477*4882a593Smuzhiyun 0x0 << AFE_24M_ON_SFT);
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x0);
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);
482*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun apll2_mux_setting(afe, false);
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
mt8183_get_apll_rate(struct mtk_base_afe * afe,int apll)487*4882a593Smuzhiyun int mt8183_get_apll_rate(struct mtk_base_afe *afe, int apll)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun return (apll == MT8183_APLL1) ? 180633600 : 196608000;
490*4882a593Smuzhiyun }
491*4882a593Smuzhiyun
mt8183_get_apll_by_rate(struct mtk_base_afe * afe,int rate)492*4882a593Smuzhiyun int mt8183_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
493*4882a593Smuzhiyun {
494*4882a593Smuzhiyun return ((rate % 8000) == 0) ? MT8183_APLL2 : MT8183_APLL1;
495*4882a593Smuzhiyun }
496*4882a593Smuzhiyun
mt8183_get_apll_by_name(struct mtk_base_afe * afe,const char * name)497*4882a593Smuzhiyun int mt8183_get_apll_by_name(struct mtk_base_afe *afe, const char *name)
498*4882a593Smuzhiyun {
499*4882a593Smuzhiyun if (strcmp(name, APLL1_W_NAME) == 0)
500*4882a593Smuzhiyun return MT8183_APLL1;
501*4882a593Smuzhiyun else
502*4882a593Smuzhiyun return MT8183_APLL2;
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun /* mck */
506*4882a593Smuzhiyun struct mt8183_mck_div {
507*4882a593Smuzhiyun int m_sel_id;
508*4882a593Smuzhiyun int div_clk_id;
509*4882a593Smuzhiyun };
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun static const struct mt8183_mck_div mck_div[MT8183_MCK_NUM] = {
512*4882a593Smuzhiyun [MT8183_I2S0_MCK] = {
513*4882a593Smuzhiyun .m_sel_id = CLK_TOP_I2S0_M_SEL,
514*4882a593Smuzhiyun .div_clk_id = CLK_TOP_APLL12_DIV0,
515*4882a593Smuzhiyun },
516*4882a593Smuzhiyun [MT8183_I2S1_MCK] = {
517*4882a593Smuzhiyun .m_sel_id = CLK_TOP_I2S1_M_SEL,
518*4882a593Smuzhiyun .div_clk_id = CLK_TOP_APLL12_DIV1,
519*4882a593Smuzhiyun },
520*4882a593Smuzhiyun [MT8183_I2S2_MCK] = {
521*4882a593Smuzhiyun .m_sel_id = CLK_TOP_I2S2_M_SEL,
522*4882a593Smuzhiyun .div_clk_id = CLK_TOP_APLL12_DIV2,
523*4882a593Smuzhiyun },
524*4882a593Smuzhiyun [MT8183_I2S3_MCK] = {
525*4882a593Smuzhiyun .m_sel_id = CLK_TOP_I2S3_M_SEL,
526*4882a593Smuzhiyun .div_clk_id = CLK_TOP_APLL12_DIV3,
527*4882a593Smuzhiyun },
528*4882a593Smuzhiyun [MT8183_I2S4_MCK] = {
529*4882a593Smuzhiyun .m_sel_id = CLK_TOP_I2S4_M_SEL,
530*4882a593Smuzhiyun .div_clk_id = CLK_TOP_APLL12_DIV4,
531*4882a593Smuzhiyun },
532*4882a593Smuzhiyun [MT8183_I2S4_BCK] = {
533*4882a593Smuzhiyun .m_sel_id = -1,
534*4882a593Smuzhiyun .div_clk_id = CLK_TOP_APLL12_DIVB,
535*4882a593Smuzhiyun },
536*4882a593Smuzhiyun [MT8183_I2S5_MCK] = {
537*4882a593Smuzhiyun .m_sel_id = -1,
538*4882a593Smuzhiyun .div_clk_id = -1,
539*4882a593Smuzhiyun },
540*4882a593Smuzhiyun };
541*4882a593Smuzhiyun
mt8183_mck_enable(struct mtk_base_afe * afe,int mck_id,int rate)542*4882a593Smuzhiyun int mt8183_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate)
543*4882a593Smuzhiyun {
544*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
545*4882a593Smuzhiyun int apll = mt8183_get_apll_by_rate(afe, rate);
546*4882a593Smuzhiyun int apll_clk_id = apll == MT8183_APLL1 ?
547*4882a593Smuzhiyun CLK_TOP_MUX_AUD_1 : CLK_TOP_MUX_AUD_2;
548*4882a593Smuzhiyun int m_sel_id = mck_div[mck_id].m_sel_id;
549*4882a593Smuzhiyun int div_clk_id = mck_div[mck_id].div_clk_id;
550*4882a593Smuzhiyun int ret;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun /* i2s5 mck not support */
553*4882a593Smuzhiyun if (mck_id == MT8183_I2S5_MCK)
554*4882a593Smuzhiyun return 0;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun /* select apll */
557*4882a593Smuzhiyun if (m_sel_id >= 0) {
558*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[m_sel_id]);
559*4882a593Smuzhiyun if (ret) {
560*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
561*4882a593Smuzhiyun __func__, aud_clks[m_sel_id], ret);
562*4882a593Smuzhiyun goto ERR_ENABLE_MCLK;
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun ret = clk_set_parent(afe_priv->clk[m_sel_id],
565*4882a593Smuzhiyun afe_priv->clk[apll_clk_id]);
566*4882a593Smuzhiyun if (ret) {
567*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
568*4882a593Smuzhiyun __func__, aud_clks[m_sel_id],
569*4882a593Smuzhiyun aud_clks[apll_clk_id], ret);
570*4882a593Smuzhiyun goto ERR_SELECT_MCLK;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun /* enable div, set rate */
575*4882a593Smuzhiyun ret = clk_prepare_enable(afe_priv->clk[div_clk_id]);
576*4882a593Smuzhiyun if (ret) {
577*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
578*4882a593Smuzhiyun __func__, aud_clks[div_clk_id], ret);
579*4882a593Smuzhiyun goto ERR_ENABLE_MCLK_DIV;
580*4882a593Smuzhiyun }
581*4882a593Smuzhiyun ret = clk_set_rate(afe_priv->clk[div_clk_id], rate);
582*4882a593Smuzhiyun if (ret) {
583*4882a593Smuzhiyun dev_err(afe->dev, "%s(), clk_set_rate %s, rate %d, fail %d\n",
584*4882a593Smuzhiyun __func__, aud_clks[div_clk_id],
585*4882a593Smuzhiyun rate, ret);
586*4882a593Smuzhiyun goto ERR_SET_MCLK_RATE;
587*4882a593Smuzhiyun return ret;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun return 0;
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun ERR_SET_MCLK_RATE:
593*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[div_clk_id]);
594*4882a593Smuzhiyun ERR_ENABLE_MCLK_DIV:
595*4882a593Smuzhiyun ERR_SELECT_MCLK:
596*4882a593Smuzhiyun if (m_sel_id >= 0)
597*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[m_sel_id]);
598*4882a593Smuzhiyun ERR_ENABLE_MCLK:
599*4882a593Smuzhiyun return ret;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun
mt8183_mck_disable(struct mtk_base_afe * afe,int mck_id)602*4882a593Smuzhiyun void mt8183_mck_disable(struct mtk_base_afe *afe, int mck_id)
603*4882a593Smuzhiyun {
604*4882a593Smuzhiyun struct mt8183_afe_private *afe_priv = afe->platform_priv;
605*4882a593Smuzhiyun int m_sel_id = mck_div[mck_id].m_sel_id;
606*4882a593Smuzhiyun int div_clk_id = mck_div[mck_id].div_clk_id;
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun /* i2s5 mck not support */
609*4882a593Smuzhiyun if (mck_id == MT8183_I2S5_MCK)
610*4882a593Smuzhiyun return;
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[div_clk_id]);
613*4882a593Smuzhiyun if (m_sel_id >= 0)
614*4882a593Smuzhiyun clk_disable_unprepare(afe_priv->clk[m_sel_id]);
615*4882a593Smuzhiyun }
616