ccu_div.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright (c) 2016 Maxime Ripard. All rights reserved.
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  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. #ifndef _CCU_DIV_H_
  14. #define _CCU_DIV_H_
  15. #include <linux/clk-provider.h>
  16. #include "ccu_common.h"
  17. #include "ccu_mux.h"
  18. /**
  19. * struct ccu_div_internal - Internal divider description
  20. * @shift: Bit offset of the divider in its register
  21. * @width: Width of the divider field in its register
  22. * @max: Maximum value allowed for that divider. This is the
  23. * arithmetic value, not the maximum value to be set in the
  24. * register.
  25. * @flags: clk_divider flags to apply on this divider
  26. * @table: Divider table pointer (if applicable)
  27. *
  28. * That structure represents a single divider, and is meant to be
  29. * embedded in other structures representing the various clock
  30. * classes.
  31. *
  32. * It is basically a wrapper around the clk_divider functions
  33. * arguments.
  34. */
  35. struct ccu_div_internal {
  36. u8 shift;
  37. u8 width;
  38. u32 max;
  39. u32 offset;
  40. u32 flags;
  41. struct clk_div_table *table;
  42. };
  43. #define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags) \
  44. { \
  45. .shift = _shift, \
  46. .width = _width, \
  47. .flags = _flags, \
  48. .table = _table, \
  49. }
  50. #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
  51. _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
  52. #define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
  53. { \
  54. .shift = _shift, \
  55. .width = _width, \
  56. .flags = _flags, \
  57. .max = _max, \
  58. .offset = _off, \
  59. }
  60. #define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
  61. _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
  62. #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
  63. _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
  64. #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \
  65. _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
  66. #define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset) \
  67. _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
  68. #define _SUNXI_CCU_DIV(_shift, _width) \
  69. _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
  70. struct ccu_div {
  71. u32 enable;
  72. struct ccu_div_internal div;
  73. struct ccu_mux_internal mux;
  74. struct ccu_common common;
  75. };
  76. #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
  77. _shift, _width, \
  78. _table, _gate, _flags) \
  79. struct ccu_div _struct = { \
  80. .div = _SUNXI_CCU_DIV_TABLE(_shift, _width, \
  81. _table), \
  82. .enable = _gate, \
  83. .common = { \
  84. .reg = _reg, \
  85. .hw.init = CLK_HW_INIT(_name, \
  86. _parent, \
  87. &ccu_div_ops, \
  88. _flags), \
  89. } \
  90. }
  91. #define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg, \
  92. _shift, _width, \
  93. _table, _flags) \
  94. SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
  95. _shift, _width, _table, 0, \
  96. _flags)
  97. #define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
  98. _parents, _table, \
  99. _reg, \
  100. _mshift, _mwidth, \
  101. _muxshift, _muxwidth, \
  102. _gate, _flags) \
  103. struct ccu_div _struct = { \
  104. .enable = _gate, \
  105. .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
  106. .mux = _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
  107. .common = { \
  108. .reg = _reg, \
  109. .hw.init = CLK_HW_INIT_PARENTS(_name, \
  110. _parents, \
  111. &ccu_div_ops, \
  112. _flags), \
  113. }, \
  114. }
  115. #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
  116. _mshift, _mwidth, _muxshift, _muxwidth, \
  117. _gate, _flags) \
  118. SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
  119. _parents, NULL, \
  120. _reg, _mshift, _mwidth, \
  121. _muxshift, _muxwidth, \
  122. _gate, _flags)
  123. #define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \
  124. _mshift, _mwidth, _muxshift, _muxwidth, \
  125. _flags) \
  126. SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
  127. _parents, NULL, \
  128. _reg, _mshift, _mwidth, \
  129. _muxshift, _muxwidth, \
  130. 0, _flags)
  131. #define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
  132. _mshift, _mwidth, _gate, \
  133. _flags) \
  134. struct ccu_div _struct = { \
  135. .enable = _gate, \
  136. .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
  137. .common = { \
  138. .reg = _reg, \
  139. .hw.init = CLK_HW_INIT(_name, \
  140. _parent, \
  141. &ccu_div_ops, \
  142. _flags), \
  143. }, \
  144. }
  145. #define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth, \
  146. _flags) \
  147. SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
  148. _mshift, _mwidth, 0, _flags)
  149. static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
  150. {
  151. struct ccu_common *common = hw_to_ccu_common(hw);
  152. return container_of(common, struct ccu_div, common);
  153. }
  154. extern const struct clk_ops ccu_div_ops;
  155. #endif /* _CCU_DIV_H_ */