clkc.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (c) 2015 Endless Mobile, Inc.
  3. * Author: Carlo Caione <carlo@endlessm.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef __CLKC_H
  18. #define __CLKC_H
  19. #define PMASK(width) GENMASK(width - 1, 0)
  20. #define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
  21. #define CLRPMASK(width, shift) (~SETPMASK(width, shift))
  22. #define PARM_GET(width, shift, reg) \
  23. (((reg) & SETPMASK(width, shift)) >> (shift))
  24. #define PARM_SET(width, shift, reg, val) \
  25. (((reg) & CLRPMASK(width, shift)) | (val << (shift)))
  26. #define MESON_PARM_APPLICABLE(p) (!!((p)->width))
  27. struct parm {
  28. u16 reg_off;
  29. u8 shift;
  30. u8 width;
  31. };
  32. #define PARM(_r, _s, _w) \
  33. { \
  34. .reg_off = (_r), \
  35. .shift = (_s), \
  36. .width = (_w), \
  37. } \
  38. struct pll_rate_table {
  39. unsigned long rate;
  40. u16 m;
  41. u16 n;
  42. u16 od;
  43. };
  44. #define PLL_RATE(_r, _m, _n, _od) \
  45. { \
  46. .rate = (_r), \
  47. .m = (_m), \
  48. .n = (_n), \
  49. .od = (_od), \
  50. } \
  51. struct pll_conf {
  52. const struct pll_rate_table *rate_table;
  53. struct parm m;
  54. struct parm n;
  55. struct parm od;
  56. };
  57. struct fixed_fact_conf {
  58. unsigned int div;
  59. unsigned int mult;
  60. struct parm div_parm;
  61. struct parm mult_parm;
  62. };
  63. struct fixed_rate_conf {
  64. unsigned long rate;
  65. struct parm rate_parm;
  66. };
  67. struct composite_conf {
  68. struct parm mux_parm;
  69. struct parm div_parm;
  70. struct parm gate_parm;
  71. struct clk_div_table *div_table;
  72. u32 *mux_table;
  73. u8 mux_flags;
  74. u8 div_flags;
  75. u8 gate_flags;
  76. };
  77. #define PNAME(x) static const char *x[]
  78. enum clk_type {
  79. CLK_FIXED_FACTOR,
  80. CLK_FIXED_RATE,
  81. CLK_COMPOSITE,
  82. CLK_CPU,
  83. CLK_PLL,
  84. };
  85. struct clk_conf {
  86. u16 reg_off;
  87. enum clk_type clk_type;
  88. unsigned int clk_id;
  89. const char *clk_name;
  90. const char **clks_parent;
  91. int num_parents;
  92. unsigned long flags;
  93. union {
  94. struct fixed_fact_conf fixed_fact;
  95. struct fixed_rate_conf fixed_rate;
  96. const struct composite_conf *composite;
  97. struct pll_conf *pll;
  98. const struct clk_div_table *div_table;
  99. } conf;
  100. };
  101. #define FIXED_RATE_P(_ro, _ci, _cn, _f, _c) \
  102. { \
  103. .reg_off = (_ro), \
  104. .clk_type = CLK_FIXED_RATE, \
  105. .clk_id = (_ci), \
  106. .clk_name = (_cn), \
  107. .flags = (_f), \
  108. .conf.fixed_rate.rate_parm = _c, \
  109. } \
  110. #define FIXED_RATE(_ci, _cn, _f, _r) \
  111. { \
  112. .clk_type = CLK_FIXED_RATE, \
  113. .clk_id = (_ci), \
  114. .clk_name = (_cn), \
  115. .flags = (_f), \
  116. .conf.fixed_rate.rate = (_r), \
  117. } \
  118. #define PLL(_ro, _ci, _cn, _cp, _f, _c) \
  119. { \
  120. .reg_off = (_ro), \
  121. .clk_type = CLK_PLL, \
  122. .clk_id = (_ci), \
  123. .clk_name = (_cn), \
  124. .clks_parent = (_cp), \
  125. .num_parents = ARRAY_SIZE(_cp), \
  126. .flags = (_f), \
  127. .conf.pll = (_c), \
  128. } \
  129. #define FIXED_FACTOR_DIV(_ci, _cn, _cp, _f, _d) \
  130. { \
  131. .clk_type = CLK_FIXED_FACTOR, \
  132. .clk_id = (_ci), \
  133. .clk_name = (_cn), \
  134. .clks_parent = (_cp), \
  135. .num_parents = ARRAY_SIZE(_cp), \
  136. .conf.fixed_fact.div = (_d), \
  137. } \
  138. #define CPU(_ro, _ci, _cn, _cp, _dt) \
  139. { \
  140. .reg_off = (_ro), \
  141. .clk_type = CLK_CPU, \
  142. .clk_id = (_ci), \
  143. .clk_name = (_cn), \
  144. .clks_parent = (_cp), \
  145. .num_parents = ARRAY_SIZE(_cp), \
  146. .conf.div_table = (_dt), \
  147. } \
  148. #define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c) \
  149. { \
  150. .reg_off = (_ro), \
  151. .clk_type = CLK_COMPOSITE, \
  152. .clk_id = (_ci), \
  153. .clk_name = (_cn), \
  154. .clks_parent = (_cp), \
  155. .num_parents = ARRAY_SIZE(_cp), \
  156. .flags = (_f), \
  157. .conf.composite = (_c), \
  158. } \
  159. struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
  160. void meson_clk_register_clks(const struct clk_conf *clk_confs,
  161. unsigned int nr_confs, void __iomem *clk_base);
  162. struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
  163. void __iomem *reg_base, spinlock_t *lock);
  164. struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
  165. void __iomem *reg_base, spinlock_t *lock);
  166. #endif /* __CLKC_H */