owl-pll.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // SPDX-License-Identifier: GPL-2.0+
  2. //
  3. // OWL pll clock driver
  4. //
  5. // Copyright (c) 2014 Actions Semi Inc.
  6. // Author: David Liu <liuwei@actions-semi.com>
  7. //
  8. // Copyright (c) 2018 Linaro Ltd.
  9. // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
  10. #include <linux/clk-provider.h>
  11. #include <linux/slab.h>
  12. #include <linux/io.h>
  13. #include <linux/delay.h>
  14. #include "owl-pll.h"
  15. static u32 owl_pll_calculate_mul(struct owl_pll_hw *pll_hw, unsigned long rate)
  16. {
  17. u32 mul;
  18. mul = DIV_ROUND_CLOSEST(rate, pll_hw->bfreq);
  19. if (mul < pll_hw->min_mul)
  20. mul = pll_hw->min_mul;
  21. else if (mul > pll_hw->max_mul)
  22. mul = pll_hw->max_mul;
  23. return mul &= mul_mask(pll_hw);
  24. }
  25. static unsigned long _get_table_rate(const struct clk_pll_table *table,
  26. unsigned int val)
  27. {
  28. const struct clk_pll_table *clkt;
  29. for (clkt = table; clkt->rate; clkt++)
  30. if (clkt->val == val)
  31. return clkt->rate;
  32. return 0;
  33. }
  34. static const struct clk_pll_table *_get_pll_table(
  35. const struct clk_pll_table *table, unsigned long rate)
  36. {
  37. const struct clk_pll_table *clkt;
  38. for (clkt = table; clkt->rate; clkt++) {
  39. if (clkt->rate == rate) {
  40. table = clkt;
  41. break;
  42. } else if (clkt->rate < rate)
  43. table = clkt;
  44. }
  45. return table;
  46. }
  47. static long owl_pll_round_rate(struct clk_hw *hw, unsigned long rate,
  48. unsigned long *parent_rate)
  49. {
  50. struct owl_pll *pll = hw_to_owl_pll(hw);
  51. struct owl_pll_hw *pll_hw = &pll->pll_hw;
  52. const struct clk_pll_table *clkt;
  53. u32 mul;
  54. if (pll_hw->table) {
  55. clkt = _get_pll_table(pll_hw->table, rate);
  56. return clkt->rate;
  57. }
  58. /* fixed frequency */
  59. if (pll_hw->width == 0)
  60. return pll_hw->bfreq;
  61. mul = owl_pll_calculate_mul(pll_hw, rate);
  62. return pll_hw->bfreq * mul;
  63. }
  64. static unsigned long owl_pll_recalc_rate(struct clk_hw *hw,
  65. unsigned long parent_rate)
  66. {
  67. struct owl_pll *pll = hw_to_owl_pll(hw);
  68. struct owl_pll_hw *pll_hw = &pll->pll_hw;
  69. const struct owl_clk_common *common = &pll->common;
  70. u32 val;
  71. if (pll_hw->table) {
  72. regmap_read(common->regmap, pll_hw->reg, &val);
  73. val = val >> pll_hw->shift;
  74. val &= mul_mask(pll_hw);
  75. return _get_table_rate(pll_hw->table, val);
  76. }
  77. /* fixed frequency */
  78. if (pll_hw->width == 0)
  79. return pll_hw->bfreq;
  80. regmap_read(common->regmap, pll_hw->reg, &val);
  81. val = val >> pll_hw->shift;
  82. val &= mul_mask(pll_hw);
  83. return pll_hw->bfreq * val;
  84. }
  85. static int owl_pll_is_enabled(struct clk_hw *hw)
  86. {
  87. struct owl_pll *pll = hw_to_owl_pll(hw);
  88. struct owl_pll_hw *pll_hw = &pll->pll_hw;
  89. const struct owl_clk_common *common = &pll->common;
  90. u32 reg;
  91. regmap_read(common->regmap, pll_hw->reg, &reg);
  92. return !!(reg & BIT(pll_hw->bit_idx));
  93. }
  94. static void owl_pll_set(const struct owl_clk_common *common,
  95. const struct owl_pll_hw *pll_hw, bool enable)
  96. {
  97. u32 reg;
  98. regmap_read(common->regmap, pll_hw->reg, &reg);
  99. if (enable)
  100. reg |= BIT(pll_hw->bit_idx);
  101. else
  102. reg &= ~BIT(pll_hw->bit_idx);
  103. regmap_write(common->regmap, pll_hw->reg, reg);
  104. }
  105. static int owl_pll_enable(struct clk_hw *hw)
  106. {
  107. struct owl_pll *pll = hw_to_owl_pll(hw);
  108. const struct owl_clk_common *common = &pll->common;
  109. owl_pll_set(common, &pll->pll_hw, true);
  110. return 0;
  111. }
  112. static void owl_pll_disable(struct clk_hw *hw)
  113. {
  114. struct owl_pll *pll = hw_to_owl_pll(hw);
  115. const struct owl_clk_common *common = &pll->common;
  116. owl_pll_set(common, &pll->pll_hw, false);
  117. }
  118. static int owl_pll_set_rate(struct clk_hw *hw, unsigned long rate,
  119. unsigned long parent_rate)
  120. {
  121. struct owl_pll *pll = hw_to_owl_pll(hw);
  122. struct owl_pll_hw *pll_hw = &pll->pll_hw;
  123. const struct owl_clk_common *common = &pll->common;
  124. const struct clk_pll_table *clkt;
  125. u32 val, reg;
  126. /* fixed frequency */
  127. if (pll_hw->width == 0)
  128. return 0;
  129. if (pll_hw->table) {
  130. clkt = _get_pll_table(pll_hw->table, rate);
  131. val = clkt->val;
  132. } else {
  133. val = owl_pll_calculate_mul(pll_hw, rate);
  134. }
  135. regmap_read(common->regmap, pll_hw->reg, &reg);
  136. reg &= ~mul_mask(pll_hw);
  137. reg |= val << pll_hw->shift;
  138. regmap_write(common->regmap, pll_hw->reg, reg);
  139. udelay(pll_hw->delay);
  140. return 0;
  141. }
  142. const struct clk_ops owl_pll_ops = {
  143. .enable = owl_pll_enable,
  144. .disable = owl_pll_disable,
  145. .is_enabled = owl_pll_is_enabled,
  146. .round_rate = owl_pll_round_rate,
  147. .recalc_rate = owl_pll_recalc_rate,
  148. .set_rate = owl_pll_set_rate,
  149. };