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