mt6797-afe-clk.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // mt6797-afe-clk.c -- Mediatek 6797 afe clock ctrl
  4. //
  5. // Copyright (c) 2018 MediaTek Inc.
  6. // Author: KaiChieh Chuang <[email protected]>
  7. #include <linux/clk.h>
  8. #include "mt6797-afe-common.h"
  9. #include "mt6797-afe-clk.h"
  10. enum {
  11. CLK_INFRA_SYS_AUD,
  12. CLK_INFRA_SYS_AUD_26M,
  13. CLK_TOP_MUX_AUD,
  14. CLK_TOP_MUX_AUD_BUS,
  15. CLK_TOP_SYSPLL3_D4,
  16. CLK_TOP_SYSPLL1_D4,
  17. CLK_CLK26M,
  18. CLK_NUM
  19. };
  20. static const char *aud_clks[CLK_NUM] = {
  21. [CLK_INFRA_SYS_AUD] = "infra_sys_audio_clk",
  22. [CLK_INFRA_SYS_AUD_26M] = "infra_sys_audio_26m",
  23. [CLK_TOP_MUX_AUD] = "top_mux_audio",
  24. [CLK_TOP_MUX_AUD_BUS] = "top_mux_aud_intbus",
  25. [CLK_TOP_SYSPLL3_D4] = "top_sys_pll3_d4",
  26. [CLK_TOP_SYSPLL1_D4] = "top_sys_pll1_d4",
  27. [CLK_CLK26M] = "top_clk26m_clk",
  28. };
  29. int mt6797_init_clock(struct mtk_base_afe *afe)
  30. {
  31. struct mt6797_afe_private *afe_priv = afe->platform_priv;
  32. int i;
  33. afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),
  34. GFP_KERNEL);
  35. if (!afe_priv->clk)
  36. return -ENOMEM;
  37. for (i = 0; i < CLK_NUM; i++) {
  38. afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
  39. if (IS_ERR(afe_priv->clk[i])) {
  40. dev_err(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",
  41. __func__, aud_clks[i],
  42. PTR_ERR(afe_priv->clk[i]));
  43. return PTR_ERR(afe_priv->clk[i]);
  44. }
  45. }
  46. return 0;
  47. }
  48. int mt6797_afe_enable_clock(struct mtk_base_afe *afe)
  49. {
  50. struct mt6797_afe_private *afe_priv = afe->platform_priv;
  51. int ret;
  52. ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD]);
  53. if (ret) {
  54. dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
  55. __func__, aud_clks[CLK_INFRA_SYS_AUD], ret);
  56. goto CLK_INFRA_SYS_AUDIO_ERR;
  57. }
  58. ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
  59. if (ret) {
  60. dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
  61. __func__, aud_clks[CLK_INFRA_SYS_AUD_26M], ret);
  62. goto CLK_INFRA_SYS_AUD_26M_ERR;
  63. }
  64. ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD]);
  65. if (ret) {
  66. dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
  67. __func__, aud_clks[CLK_TOP_MUX_AUD], ret);
  68. goto CLK_MUX_AUDIO_ERR;
  69. }
  70. ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD],
  71. afe_priv->clk[CLK_CLK26M]);
  72. if (ret) {
  73. dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
  74. __func__, aud_clks[CLK_TOP_MUX_AUD],
  75. aud_clks[CLK_CLK26M], ret);
  76. goto CLK_MUX_AUDIO_ERR;
  77. }
  78. ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
  79. if (ret) {
  80. dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
  81. __func__, aud_clks[CLK_TOP_MUX_AUD_BUS], ret);
  82. goto CLK_MUX_AUDIO_INTBUS_ERR;
  83. }
  84. return ret;
  85. CLK_MUX_AUDIO_INTBUS_ERR:
  86. clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
  87. CLK_MUX_AUDIO_ERR:
  88. clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);
  89. CLK_INFRA_SYS_AUD_26M_ERR:
  90. clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
  91. CLK_INFRA_SYS_AUDIO_ERR:
  92. clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);
  93. return 0;
  94. }
  95. int mt6797_afe_disable_clock(struct mtk_base_afe *afe)
  96. {
  97. struct mt6797_afe_private *afe_priv = afe->platform_priv;
  98. clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
  99. clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);
  100. clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
  101. clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);
  102. return 0;
  103. }