clk-programmable.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
  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 as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. */
  10. #include <linux/clk-provider.h>
  11. #include <linux/clkdev.h>
  12. #include <linux/clk/at91_pmc.h>
  13. #include <linux/of.h>
  14. #include <linux/mfd/syscon.h>
  15. #include <linux/regmap.h>
  16. #include "pmc.h"
  17. #define PROG_ID_MAX 7
  18. #define PROG_STATUS_MASK(id) (1 << ((id) + 8))
  19. #define PROG_PRES_MASK 0x7
  20. #define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & PROG_PRES_MASK)
  21. #define PROG_MAX_RM9200_CSS 3
  22. struct clk_programmable {
  23. struct clk_hw hw;
  24. struct regmap *regmap;
  25. u8 id;
  26. const struct clk_programmable_layout *layout;
  27. };
  28. #define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw)
  29. static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
  30. unsigned long parent_rate)
  31. {
  32. struct clk_programmable *prog = to_clk_programmable(hw);
  33. unsigned int pckr;
  34. regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr);
  35. return parent_rate >> PROG_PRES(prog->layout, pckr);
  36. }
  37. static int clk_programmable_determine_rate(struct clk_hw *hw,
  38. struct clk_rate_request *req)
  39. {
  40. struct clk_hw *parent;
  41. long best_rate = -EINVAL;
  42. unsigned long parent_rate;
  43. unsigned long tmp_rate;
  44. int shift;
  45. int i;
  46. for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
  47. parent = clk_hw_get_parent_by_index(hw, i);
  48. if (!parent)
  49. continue;
  50. parent_rate = clk_hw_get_rate(parent);
  51. for (shift = 0; shift < PROG_PRES_MASK; shift++) {
  52. tmp_rate = parent_rate >> shift;
  53. if (tmp_rate <= req->rate)
  54. break;
  55. }
  56. if (tmp_rate > req->rate)
  57. continue;
  58. if (best_rate < 0 ||
  59. (req->rate - tmp_rate) < (req->rate - best_rate)) {
  60. best_rate = tmp_rate;
  61. req->best_parent_rate = parent_rate;
  62. req->best_parent_hw = parent;
  63. }
  64. if (!best_rate)
  65. break;
  66. }
  67. if (best_rate < 0)
  68. return best_rate;
  69. req->rate = best_rate;
  70. return 0;
  71. }
  72. static int clk_programmable_set_parent(struct clk_hw *hw, u8 index)
  73. {
  74. struct clk_programmable *prog = to_clk_programmable(hw);
  75. const struct clk_programmable_layout *layout = prog->layout;
  76. unsigned int mask = layout->css_mask;
  77. unsigned int pckr = index;
  78. if (layout->have_slck_mck)
  79. mask |= AT91_PMC_CSSMCK_MCK;
  80. if (index > layout->css_mask) {
  81. if (index > PROG_MAX_RM9200_CSS && !layout->have_slck_mck)
  82. return -EINVAL;
  83. pckr |= AT91_PMC_CSSMCK_MCK;
  84. }
  85. regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id), mask, pckr);
  86. return 0;
  87. }
  88. static u8 clk_programmable_get_parent(struct clk_hw *hw)
  89. {
  90. struct clk_programmable *prog = to_clk_programmable(hw);
  91. const struct clk_programmable_layout *layout = prog->layout;
  92. unsigned int pckr;
  93. u8 ret;
  94. regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr);
  95. ret = pckr & layout->css_mask;
  96. if (layout->have_slck_mck && (pckr & AT91_PMC_CSSMCK_MCK) && !ret)
  97. ret = PROG_MAX_RM9200_CSS + 1;
  98. return ret;
  99. }
  100. static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
  101. unsigned long parent_rate)
  102. {
  103. struct clk_programmable *prog = to_clk_programmable(hw);
  104. const struct clk_programmable_layout *layout = prog->layout;
  105. unsigned long div = parent_rate / rate;
  106. unsigned int pckr;
  107. int shift = 0;
  108. regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr);
  109. if (!div)
  110. return -EINVAL;
  111. shift = fls(div) - 1;
  112. if (div != (1 << shift))
  113. return -EINVAL;
  114. if (shift >= PROG_PRES_MASK)
  115. return -EINVAL;
  116. regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id),
  117. PROG_PRES_MASK << layout->pres_shift,
  118. shift << layout->pres_shift);
  119. return 0;
  120. }
  121. static const struct clk_ops programmable_ops = {
  122. .recalc_rate = clk_programmable_recalc_rate,
  123. .determine_rate = clk_programmable_determine_rate,
  124. .get_parent = clk_programmable_get_parent,
  125. .set_parent = clk_programmable_set_parent,
  126. .set_rate = clk_programmable_set_rate,
  127. };
  128. struct clk_hw * __init
  129. at91_clk_register_programmable(struct regmap *regmap,
  130. const char *name, const char **parent_names,
  131. u8 num_parents, u8 id,
  132. const struct clk_programmable_layout *layout)
  133. {
  134. struct clk_programmable *prog;
  135. struct clk_hw *hw;
  136. struct clk_init_data init;
  137. int ret;
  138. if (id > PROG_ID_MAX)
  139. return ERR_PTR(-EINVAL);
  140. prog = kzalloc(sizeof(*prog), GFP_KERNEL);
  141. if (!prog)
  142. return ERR_PTR(-ENOMEM);
  143. init.name = name;
  144. init.ops = &programmable_ops;
  145. init.parent_names = parent_names;
  146. init.num_parents = num_parents;
  147. init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
  148. prog->id = id;
  149. prog->layout = layout;
  150. prog->hw.init = &init;
  151. prog->regmap = regmap;
  152. hw = &prog->hw;
  153. ret = clk_hw_register(NULL, &prog->hw);
  154. if (ret) {
  155. kfree(prog);
  156. hw = ERR_PTR(ret);
  157. } else {
  158. pmc_register_pck(id);
  159. }
  160. return hw;
  161. }
  162. const struct clk_programmable_layout at91rm9200_programmable_layout = {
  163. .pres_shift = 2,
  164. .css_mask = 0x3,
  165. .have_slck_mck = 0,
  166. };
  167. const struct clk_programmable_layout at91sam9g45_programmable_layout = {
  168. .pres_shift = 2,
  169. .css_mask = 0x3,
  170. .have_slck_mck = 1,
  171. };
  172. const struct clk_programmable_layout at91sam9x5_programmable_layout = {
  173. .pres_shift = 4,
  174. .css_mask = 0x7,
  175. .have_slck_mck = 0,
  176. };