dsi_pll.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. int ret;
  63. /*
  64. * Certain PLLs need to update the same VCO rate and registers
  65. * after resume in suspend/resume scenario.
  66. */
  67. if (pll->restore_state) {
  68. ret = pll->restore_state(pll);
  69. if (ret)
  70. goto error;
  71. }
  72. ret = dsi_pll_enable(pll);
  73. error:
  74. return ret;
  75. }
  76. void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw)
  77. {
  78. struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
  79. if (pll->save_state)
  80. pll->save_state(pll);
  81. dsi_pll_disable(pll);
  82. }
  83. void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev,
  84. struct clk **clks, u32 num_clks)
  85. {
  86. of_clk_del_provider(pdev->dev.of_node);
  87. if (!num_clks || !clks)
  88. return;
  89. do {
  90. clk_unregister(clks[--num_clks]);
  91. clks[num_clks] = NULL;
  92. } while (num_clks);
  93. }
  94. /*
  95. * DSI PLL API
  96. */
  97. int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
  98. struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
  99. {
  100. if (pll->get_provider)
  101. return pll->get_provider(pll,
  102. byte_clk_provider,
  103. pixel_clk_provider);
  104. return -EINVAL;
  105. }
  106. void msm_dsi_pll_destroy(struct msm_dsi_pll *pll)
  107. {
  108. if (pll->destroy)
  109. pll->destroy(pll);
  110. }
  111. struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
  112. enum msm_dsi_phy_type type, int id)
  113. {
  114. struct device *dev = &pdev->dev;
  115. struct msm_dsi_pll *pll;
  116. switch (type) {
  117. case MSM_DSI_PHY_28NM_HPM:
  118. case MSM_DSI_PHY_28NM_LP:
  119. pll = msm_dsi_pll_28nm_init(pdev, type, id);
  120. break;
  121. default:
  122. pll = ERR_PTR(-ENXIO);
  123. break;
  124. }
  125. if (IS_ERR(pll)) {
  126. dev_err(dev, "%s: failed to init DSI PLL\n", __func__);
  127. return NULL;
  128. }
  129. pll->type = type;
  130. DBG("DSI:%d PLL registered", id);
  131. return pll;
  132. }