mt2701-afe-clock-ctrl.c 8.0 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3 4 5 6
/*
 * mt2701-afe-clock-ctrl.c  --  Mediatek 2701 afe clock ctrl
 *
 * Copyright (c) 2016 MediaTek Inc.
 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
7
 *	   Ryder Lee <ryder.lee@mediatek.com>
8 9 10 11 12
 */

#include "mt2701-afe-common.h"
#include "mt2701-afe-clock-ctrl.h"

13
static const char *const base_clks[] = {
14
	[MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
15 16
	[MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel",
	[MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel",
17 18
	[MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp",
	[MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp",
19 20 21 22
	[MT2701_AUDSYS_AFE] = "audio_afe_pd",
	[MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd",
	[MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd",
	[MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd",
23 24 25 26 27
};

int mt2701_init_clock(struct mtk_base_afe *afe)
{
	struct mt2701_afe_private *afe_priv = afe->platform_priv;
28 29 30 31 32 33 34
	int i;

	for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
		afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]);
		if (IS_ERR(afe_priv->base_ck[i])) {
			dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
			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 45 46 47 48 49
		snprintf(name, sizeof(name), "i2s%d_src_sel", i);
		i2s_path->sel_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_path->sel_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_path->sel_ck);
		}
50

51 52 53 54 55 56
		snprintf(name, sizeof(name), "i2s%d_src_div", i);
		i2s_path->div_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_path->div_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_path->div_ck);
		}
57

58 59 60 61 62 63
		snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
		i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_path->mclk_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_path->mclk_ck);
		}
64

65
		snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
66 67
		i2s_ck = devm_clk_get(afe->dev, name);
		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 75
		i2s_ck = devm_clk_get(afe->dev, name);
		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 82 83 84 85 86

		snprintf(name, sizeof(name), "asrc%d_out_ck", i);
		i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_path->asrco_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_path->asrco_ck);
		}
87 88
	}

89 90 91 92 93
	/* Some platforms may support BT path */
	afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
	if (IS_ERR(afe_priv->mrgif_ck)) {
		if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
94

95 96
		afe_priv->mrgif_ck = NULL;
	}
97

98
	return 0;
99 100
}

101 102 103
int mt2701_afe_enable_i2s(struct mtk_base_afe *afe,
			  struct mt2701_i2s_path *i2s_path,
			  int dir)
104
{
105
	int ret;
106

107
	ret = clk_prepare_enable(i2s_path->asrco_ck);
108
	if (ret) {
109 110
		dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret);
		return ret;
111 112
	}

113
	ret = clk_prepare_enable(i2s_path->hop_ck[dir]);
114
	if (ret) {
115 116
		dev_err(afe->dev, "failed to enable I2S clock %d\n", ret);
		goto err_hop_ck;
117 118
	}

119
	return 0;
120

121 122
err_hop_ck:
	clk_disable_unprepare(i2s_path->asrco_ck);
123

124 125
	return ret;
}
126

127 128 129
void mt2701_afe_disable_i2s(struct mtk_base_afe *afe,
			    struct mt2701_i2s_path *i2s_path,
			    int dir)
130 131 132 133
{
	clk_disable_unprepare(i2s_path->hop_ck[dir]);
	clk_disable_unprepare(i2s_path->asrco_ck);
}
134

135 136 137 138
int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id)
{
	struct mt2701_afe_private *afe_priv = afe->platform_priv;
	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 154
{
	struct mt2701_afe_private *afe_priv = afe->platform_priv;

155 156
	return clk_prepare_enable(afe_priv->mrgif_ck);
}
157

158 159 160
void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe)
{
	struct mt2701_afe_private *afe_priv = afe->platform_priv;
161

162 163
	clk_disable_unprepare(afe_priv->mrgif_ck);
}
164

165 166 167 168
static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
{
	struct mt2701_afe_private *afe_priv = afe->platform_priv;
	int ret;
169

170 171
	/* Enable infra clock gate */
	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
172 173
	if (ret)
		return ret;
174

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
	/* Enable top a1sys clock gate */
	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
	if (ret)
		goto err_a1sys;

	/* Enable top a2sys clock gate */
	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
	if (ret)
		goto err_a2sys;

	/* Internal clock gates */
	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
	if (ret)
		goto err_afe;

190 191 192 193 194 195 196 197 198 199 200
	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
	if (ret)
		goto err_audio_a1sys;

	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
	if (ret)
		goto err_audio_a2sys;

	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
	if (ret)
		goto err_afe_conn;
201 202 203

	return 0;

204 205 206 207 208 209
err_afe_conn:
	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
err_audio_a2sys:
	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
err_audio_a1sys:
	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
210 211 212 213 214 215
err_afe:
	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
err_a2sys:
	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
err_a1sys:
	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
216 217 218 219

	return ret;
}

220
static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
221 222 223
{
	struct mt2701_afe_private *afe_priv = afe->platform_priv;

224 225 226 227
	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
228 229 230
	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
	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 236
{
	int ret;

237 238
	/* Enable audio system */
	ret = mt2701_afe_enable_audsys(afe);
239
	if (ret) {
240 241
		dev_err(afe->dev, "failed to enable audio system %d\n", ret);
		return ret;
242 243
	}

244
	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
245 246
			   ASYS_TOP_CON_ASYS_TIMING_ON,
			   ASYS_TOP_CON_ASYS_TIMING_ON);
247 248 249
	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
			   AFE_DAC_CON0_AFE_ON,
			   AFE_DAC_CON0_AFE_ON);
250

251 252 253
	/* Configure ASRC */
	regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL);
	regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL);
254 255 256 257

	return 0;
}

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 263
	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
			   AFE_DAC_CON0_AFE_ON, 0);
264

265 266 267
	mt2701_afe_disable_audsys(afe);

	return 0;
268 269
}

270 271
int mt2701_mclk_configuration(struct mtk_base_afe *afe, int id)

272
{
273 274
	struct mt2701_afe_private *priv = afe->platform_priv;
	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 280
		ret = clk_set_parent(i2s_path->sel_ck,
				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
281
	else if (!(MT2701_PLL_DOMAIN_1_RATE % i2s_path->mclk_rate))
282 283
		ret = clk_set_parent(i2s_path->sel_ck,
				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
284

285 286 287 288
	if (ret) {
		dev_err(afe->dev, "failed to set mclk source\n");
		return ret;
	}
289

290
	/* Set mclk divider */
291 292
	ret = clk_set_rate(i2s_path->div_ck, i2s_path->mclk_rate);
	if (ret) {
293
		dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
294 295 296 297
		return ret;
	}

	return 0;
298
}