dsi_pll.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include "dsi_pll.h"
  14. static int dsi_pll_enable(struct msm_dsi_pll *pll)
  15. {
  16. int i, ret = 0;
  17. /*
  18. * Certain PLLs do not allow VCO rate update when it is on.
  19. * Keep track of their status to turn on/off after set rate success.
  20. */
  21. if (unlikely(pll->pll_on))
  22. return 0;
  23. /* Try all enable sequences until one succeeds */
  24. for (i = 0; i < pll->en_seq_cnt; i++) {
  25. ret = pll->enable_seqs[i](pll);
  26. DBG("DSI PLL %s after sequence #%d",
  27. ret ? "unlocked" : "locked", i + 1);
  28. if (!ret)
  29. break;
  30. }
  31. if (ret) {
  32. DRM_ERROR("DSI PLL failed to lock\n");
  33. return ret;
  34. }
  35. pll->pll_on = true;
  36. return 0;
  37. }
  38. static void dsi_pll_disable(struct msm_dsi_pll *pll)
  39. {
  40. if (unlikely(!pll->pll_on))
  41. return;
  42. pll->disable_seq(pll);
  43. pll->pll_on = false;
  44. }
  45. /*
  46. * DSI PLL Helper functions
  47. */
  48. long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw,
  49. unsigned long rate, unsigned long *parent_rate)
  50. {
  51. struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
  52. if (rate < pll->min_rate)
  53. return pll->min_rate;
  54. else if (rate > pll->max_rate)
  55. return pll->max_rate;
  56. else
  57. return rate;
  58. }
  59. int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw)
  60. {
  61. struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
  62. return dsi_pll_enable(pll);
  63. }
  64. void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw)
  65. {
  66. struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
  67. dsi_pll_disable(pll);
  68. }
  69. void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev,
  70. struct clk **clks, u32 num_clks)
  71. {
  72. of_clk_del_provider(pdev->dev.of_node);
  73. if (!num_clks || !clks)
  74. return;
  75. do {
  76. clk_unregister(clks[--num_clks]);
  77. clks[num_clks] = NULL;
  78. } while (num_clks);
  79. }
  80. /*
  81. * DSI PLL API
  82. */
  83. int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
  84. struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
  85. {
  86. if (pll->get_provider)
  87. return pll->get_provider(pll,
  88. byte_clk_provider,
  89. pixel_clk_provider);
  90. return -EINVAL;
  91. }
  92. void msm_dsi_pll_destroy(struct msm_dsi_pll *pll)
  93. {
  94. if (pll->destroy)
  95. pll->destroy(pll);
  96. }
  97. void msm_dsi_pll_save_state(struct msm_dsi_pll *pll)
  98. {
  99. if (pll->save_state) {
  100. pll->save_state(pll);
  101. pll->state_saved = true;
  102. }
  103. }
  104. int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll)
  105. {
  106. int ret;
  107. if (pll->restore_state && pll->state_saved) {
  108. ret = pll->restore_state(pll);
  109. if (ret)
  110. return ret;
  111. pll->state_saved = false;
  112. }
  113. return 0;
  114. }
  115. struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
  116. enum msm_dsi_phy_type type, int id)
  117. {
  118. struct device *dev = &pdev->dev;
  119. struct msm_dsi_pll *pll;
  120. switch (type) {
  121. case MSM_DSI_PHY_28NM_HPM:
  122. case MSM_DSI_PHY_28NM_LP:
  123. pll = msm_dsi_pll_28nm_init(pdev, type, id);
  124. break;
  125. default:
  126. pll = ERR_PTR(-ENXIO);
  127. break;
  128. }
  129. if (IS_ERR(pll)) {
  130. dev_err(dev, "%s: failed to init DSI PLL\n", __func__);
  131. return NULL;
  132. }
  133. pll->type = type;
  134. DBG("DSI:%d PLL registered", id);
  135. return pll;
  136. }