cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mt2701-afe-clock-ctrl.c (8231B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * mt2701-afe-clock-ctrl.c  --  Mediatek 2701 afe clock ctrl
      4 *
      5 * Copyright (c) 2016 MediaTek Inc.
      6 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
      7 *	   Ryder Lee <ryder.lee@mediatek.com>
      8 */
      9
     10#include "mt2701-afe-common.h"
     11#include "mt2701-afe-clock-ctrl.h"
     12
     13static const char *const base_clks[] = {
     14	[MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
     15	[MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel",
     16	[MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel",
     17	[MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp",
     18	[MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp",
     19	[MT2701_AUDSYS_AFE] = "audio_afe_pd",
     20	[MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd",
     21	[MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd",
     22	[MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd",
     23};
     24
     25int mt2701_init_clock(struct mtk_base_afe *afe)
     26{
     27	struct mt2701_afe_private *afe_priv = afe->platform_priv;
     28	int i;
     29
     30	for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
     31		afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]);
     32		if (IS_ERR(afe_priv->base_ck[i])) {
     33			dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
     34			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		snprintf(name, sizeof(name), "i2s%d_src_sel", i);
     45		i2s_path->sel_ck = devm_clk_get(afe->dev, name);
     46		if (IS_ERR(i2s_path->sel_ck)) {
     47			dev_err(afe->dev, "failed to get %s\n", name);
     48			return PTR_ERR(i2s_path->sel_ck);
     49		}
     50
     51		snprintf(name, sizeof(name), "i2s%d_src_div", i);
     52		i2s_path->div_ck = devm_clk_get(afe->dev, name);
     53		if (IS_ERR(i2s_path->div_ck)) {
     54			dev_err(afe->dev, "failed to get %s\n", name);
     55			return PTR_ERR(i2s_path->div_ck);
     56		}
     57
     58		snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
     59		i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
     60		if (IS_ERR(i2s_path->mclk_ck)) {
     61			dev_err(afe->dev, "failed to get %s\n", name);
     62			return PTR_ERR(i2s_path->mclk_ck);
     63		}
     64
     65		snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
     66		i2s_ck = devm_clk_get(afe->dev, name);
     67		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		i2s_ck = devm_clk_get(afe->dev, name);
     75		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		snprintf(name, sizeof(name), "asrc%d_out_ck", i);
     82		i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
     83		if (IS_ERR(i2s_path->asrco_ck)) {
     84			dev_err(afe->dev, "failed to get %s\n", name);
     85			return PTR_ERR(i2s_path->asrco_ck);
     86		}
     87	}
     88
     89	/* Some platforms may support BT path */
     90	afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
     91	if (IS_ERR(afe_priv->mrgif_ck)) {
     92		if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
     93			return -EPROBE_DEFER;
     94
     95		afe_priv->mrgif_ck = NULL;
     96	}
     97
     98	return 0;
     99}
    100
    101int mt2701_afe_enable_i2s(struct mtk_base_afe *afe,
    102			  struct mt2701_i2s_path *i2s_path,
    103			  int dir)
    104{
    105	int ret;
    106
    107	ret = clk_prepare_enable(i2s_path->asrco_ck);
    108	if (ret) {
    109		dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret);
    110		return ret;
    111	}
    112
    113	ret = clk_prepare_enable(i2s_path->hop_ck[dir]);
    114	if (ret) {
    115		dev_err(afe->dev, "failed to enable I2S clock %d\n", ret);
    116		goto err_hop_ck;
    117	}
    118
    119	return 0;
    120
    121err_hop_ck:
    122	clk_disable_unprepare(i2s_path->asrco_ck);
    123
    124	return ret;
    125}
    126
    127void mt2701_afe_disable_i2s(struct mtk_base_afe *afe,
    128			    struct mt2701_i2s_path *i2s_path,
    129			    int dir)
    130{
    131	clk_disable_unprepare(i2s_path->hop_ck[dir]);
    132	clk_disable_unprepare(i2s_path->asrco_ck);
    133}
    134
    135int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id)
    136{
    137	struct mt2701_afe_private *afe_priv = afe->platform_priv;
    138	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
    139
    140	return clk_prepare_enable(i2s_path->mclk_ck);
    141}
    142
    143void 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
    151int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe)
    152{
    153	struct mt2701_afe_private *afe_priv = afe->platform_priv;
    154
    155	return clk_prepare_enable(afe_priv->mrgif_ck);
    156}
    157
    158void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe)
    159{
    160	struct mt2701_afe_private *afe_priv = afe->platform_priv;
    161
    162	clk_disable_unprepare(afe_priv->mrgif_ck);
    163}
    164
    165static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
    166{
    167	struct mt2701_afe_private *afe_priv = afe->platform_priv;
    168	int ret;
    169
    170	/* Enable infra clock gate */
    171	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
    172	if (ret)
    173		return ret;
    174
    175	/* Enable top a1sys clock gate */
    176	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
    177	if (ret)
    178		goto err_a1sys;
    179
    180	/* Enable top a2sys clock gate */
    181	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
    182	if (ret)
    183		goto err_a2sys;
    184
    185	/* Internal clock gates */
    186	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
    187	if (ret)
    188		goto err_afe;
    189
    190	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
    191	if (ret)
    192		goto err_audio_a1sys;
    193
    194	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
    195	if (ret)
    196		goto err_audio_a2sys;
    197
    198	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
    199	if (ret)
    200		goto err_afe_conn;
    201
    202	return 0;
    203
    204err_afe_conn:
    205	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
    206err_audio_a2sys:
    207	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
    208err_audio_a1sys:
    209	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
    210err_afe:
    211	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
    212err_a2sys:
    213	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
    214err_a1sys:
    215	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
    216
    217	return ret;
    218}
    219
    220static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
    221{
    222	struct mt2701_afe_private *afe_priv = afe->platform_priv;
    223
    224	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
    225	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
    226	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
    227	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
    228	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
    229	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
    230	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
    231}
    232
    233int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
    234{
    235	int ret;
    236
    237	/* Enable audio system */
    238	ret = mt2701_afe_enable_audsys(afe);
    239	if (ret) {
    240		dev_err(afe->dev, "failed to enable audio system %d\n", ret);
    241		return ret;
    242	}
    243
    244	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
    245			   ASYS_TOP_CON_ASYS_TIMING_ON,
    246			   ASYS_TOP_CON_ASYS_TIMING_ON);
    247	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
    248			   AFE_DAC_CON0_AFE_ON,
    249			   AFE_DAC_CON0_AFE_ON);
    250
    251	/* Configure ASRC */
    252	regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL);
    253	regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL);
    254
    255	return 0;
    256}
    257
    258int 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	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
    263			   AFE_DAC_CON0_AFE_ON, 0);
    264
    265	mt2701_afe_disable_audsys(afe);
    266
    267	return 0;
    268}
    269
    270int mt2701_mclk_configuration(struct mtk_base_afe *afe, int id)
    271
    272{
    273	struct mt2701_afe_private *priv = afe->platform_priv;
    274	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		ret = clk_set_parent(i2s_path->sel_ck,
    280				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
    281	else if (!(MT2701_PLL_DOMAIN_1_RATE % i2s_path->mclk_rate))
    282		ret = clk_set_parent(i2s_path->sel_ck,
    283				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
    284
    285	if (ret) {
    286		dev_err(afe->dev, "failed to set mclk source\n");
    287		return ret;
    288	}
    289
    290	/* Set mclk divider */
    291	ret = clk_set_rate(i2s_path->div_ck, i2s_path->mclk_rate);
    292	if (ret) {
    293		dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
    294		return ret;
    295	}
    296
    297	return 0;
    298}