18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci//
38c2ecf20Sopenharmony_ci// mt6797-afe-clk.c  --  Mediatek 6797 afe clock ctrl
48c2ecf20Sopenharmony_ci//
58c2ecf20Sopenharmony_ci// Copyright (c) 2018 MediaTek Inc.
68c2ecf20Sopenharmony_ci// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/clk.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "mt6797-afe-common.h"
118c2ecf20Sopenharmony_ci#include "mt6797-afe-clk.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cienum {
148c2ecf20Sopenharmony_ci	CLK_INFRA_SYS_AUD,
158c2ecf20Sopenharmony_ci	CLK_INFRA_SYS_AUD_26M,
168c2ecf20Sopenharmony_ci	CLK_TOP_MUX_AUD,
178c2ecf20Sopenharmony_ci	CLK_TOP_MUX_AUD_BUS,
188c2ecf20Sopenharmony_ci	CLK_TOP_SYSPLL3_D4,
198c2ecf20Sopenharmony_ci	CLK_TOP_SYSPLL1_D4,
208c2ecf20Sopenharmony_ci	CLK_CLK26M,
218c2ecf20Sopenharmony_ci	CLK_NUM
228c2ecf20Sopenharmony_ci};
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cistatic const char *aud_clks[CLK_NUM] = {
258c2ecf20Sopenharmony_ci	[CLK_INFRA_SYS_AUD] = "infra_sys_audio_clk",
268c2ecf20Sopenharmony_ci	[CLK_INFRA_SYS_AUD_26M] = "infra_sys_audio_26m",
278c2ecf20Sopenharmony_ci	[CLK_TOP_MUX_AUD] = "top_mux_audio",
288c2ecf20Sopenharmony_ci	[CLK_TOP_MUX_AUD_BUS] = "top_mux_aud_intbus",
298c2ecf20Sopenharmony_ci	[CLK_TOP_SYSPLL3_D4] = "top_sys_pll3_d4",
308c2ecf20Sopenharmony_ci	[CLK_TOP_SYSPLL1_D4] = "top_sys_pll1_d4",
318c2ecf20Sopenharmony_ci	[CLK_CLK26M] = "top_clk26m_clk",
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ciint mt6797_init_clock(struct mtk_base_afe *afe)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	struct mt6797_afe_private *afe_priv = afe->platform_priv;
378c2ecf20Sopenharmony_ci	int i;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),
408c2ecf20Sopenharmony_ci				     GFP_KERNEL);
418c2ecf20Sopenharmony_ci	if (!afe_priv->clk)
428c2ecf20Sopenharmony_ci		return -ENOMEM;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	for (i = 0; i < CLK_NUM; i++) {
458c2ecf20Sopenharmony_ci		afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
468c2ecf20Sopenharmony_ci		if (IS_ERR(afe_priv->clk[i])) {
478c2ecf20Sopenharmony_ci			dev_err(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",
488c2ecf20Sopenharmony_ci				__func__, aud_clks[i],
498c2ecf20Sopenharmony_ci				PTR_ERR(afe_priv->clk[i]));
508c2ecf20Sopenharmony_ci			return PTR_ERR(afe_priv->clk[i]);
518c2ecf20Sopenharmony_ci		}
528c2ecf20Sopenharmony_ci	}
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	return 0;
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ciint mt6797_afe_enable_clock(struct mtk_base_afe *afe)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	struct mt6797_afe_private *afe_priv = afe->platform_priv;
608c2ecf20Sopenharmony_ci	int ret;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD]);
638c2ecf20Sopenharmony_ci	if (ret) {
648c2ecf20Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
658c2ecf20Sopenharmony_ci			__func__, aud_clks[CLK_INFRA_SYS_AUD], ret);
668c2ecf20Sopenharmony_ci		goto CLK_INFRA_SYS_AUDIO_ERR;
678c2ecf20Sopenharmony_ci	}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
708c2ecf20Sopenharmony_ci	if (ret) {
718c2ecf20Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
728c2ecf20Sopenharmony_ci			__func__, aud_clks[CLK_INFRA_SYS_AUD_26M], ret);
738c2ecf20Sopenharmony_ci		goto CLK_INFRA_SYS_AUD_26M_ERR;
748c2ecf20Sopenharmony_ci	}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD]);
778c2ecf20Sopenharmony_ci	if (ret) {
788c2ecf20Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
798c2ecf20Sopenharmony_ci			__func__, aud_clks[CLK_TOP_MUX_AUD], ret);
808c2ecf20Sopenharmony_ci		goto CLK_MUX_AUDIO_ERR;
818c2ecf20Sopenharmony_ci	}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD],
848c2ecf20Sopenharmony_ci			     afe_priv->clk[CLK_CLK26M]);
858c2ecf20Sopenharmony_ci	if (ret) {
868c2ecf20Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
878c2ecf20Sopenharmony_ci			__func__, aud_clks[CLK_TOP_MUX_AUD],
888c2ecf20Sopenharmony_ci			aud_clks[CLK_CLK26M], ret);
898c2ecf20Sopenharmony_ci		goto CLK_MUX_AUDIO_ERR;
908c2ecf20Sopenharmony_ci	}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
938c2ecf20Sopenharmony_ci	if (ret) {
948c2ecf20Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
958c2ecf20Sopenharmony_ci			__func__, aud_clks[CLK_TOP_MUX_AUD_BUS], ret);
968c2ecf20Sopenharmony_ci		goto CLK_MUX_AUDIO_INTBUS_ERR;
978c2ecf20Sopenharmony_ci	}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	return ret;
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ciCLK_MUX_AUDIO_INTBUS_ERR:
1028c2ecf20Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
1038c2ecf20Sopenharmony_ciCLK_MUX_AUDIO_ERR:
1048c2ecf20Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);
1058c2ecf20Sopenharmony_ciCLK_INFRA_SYS_AUD_26M_ERR:
1068c2ecf20Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
1078c2ecf20Sopenharmony_ciCLK_INFRA_SYS_AUDIO_ERR:
1088c2ecf20Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	return 0;
1118c2ecf20Sopenharmony_ci}
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ciint mt6797_afe_disable_clock(struct mtk_base_afe *afe)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	struct mt6797_afe_private *afe_priv = afe->platform_priv;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
1188c2ecf20Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);
1198c2ecf20Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
1208c2ecf20Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	return 0;
1238c2ecf20Sopenharmony_ci}
124