ccu_div.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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 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 {
  36. u8 shift;
  37. u8 width;
  38. u32 max;
  39. u32 flags;
  40. struct clk_div_table *table;
  41. };
  42. #define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags) \
  43. { \
  44. .shift = _shift, \
  45. .width = _width, \
  46. .flags = _flags, \
  47. .table = _table, \
  48. }
  49. #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
  50. _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
  51. #define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
  52. { \
  53. .shift = _shift, \
  54. .width = _width, \
  55. .flags = _flags, \
  56. .max = _max, \
  57. }
  58. #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
  59. _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
  60. #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \
  61. _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
  62. #define _SUNXI_CCU_DIV(_shift, _width) \
  63. _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
  64. struct ccu_div {
  65. u32 enable;
  66. struct _ccu_div div;
  67. struct ccu_mux_internal mux;
  68. struct ccu_common common;
  69. };
  70. #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
  71. _shift, _width, \
  72. _table, _gate, _flags) \
  73. struct ccu_div _struct = { \
  74. .div = _SUNXI_CCU_DIV_TABLE(_shift, _width, \
  75. _table), \
  76. .enable = _gate, \
  77. .common = { \
  78. .reg = _reg, \
  79. .hw.init = CLK_HW_INIT(_name, \
  80. _parent, \
  81. &ccu_div_ops, \
  82. _flags), \
  83. } \
  84. }
  85. #define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg, \
  86. _shift, _width, \
  87. _table, _flags) \
  88. SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
  89. _shift, _width, _table, 0, \
  90. _flags)
  91. #define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
  92. _parents, _table, \
  93. _reg, \
  94. _mshift, _mwidth, \
  95. _muxshift, _muxwidth, \
  96. _gate, _flags) \
  97. struct ccu_div _struct = { \
  98. .enable = _gate, \
  99. .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
  100. .mux = _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
  101. .common = { \
  102. .reg = _reg, \
  103. .hw.init = CLK_HW_INIT_PARENTS(_name, \
  104. _parents, \
  105. &ccu_div_ops, \
  106. _flags), \
  107. }, \
  108. }
  109. #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
  110. _mshift, _mwidth, _muxshift, _muxwidth, \
  111. _gate, _flags) \
  112. SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
  113. _parents, NULL, \
  114. _reg, _mshift, _mwidth, \
  115. _muxshift, _muxwidth, \
  116. _gate, _flags)
  117. #define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \
  118. _mshift, _mwidth, _muxshift, _muxwidth, \
  119. _flags) \
  120. SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
  121. _parents, NULL, \
  122. _reg, _mshift, _mwidth, \
  123. _muxshift, _muxwidth, \
  124. 0, _flags)
  125. #define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
  126. _mshift, _mwidth, _gate, \
  127. _flags) \
  128. struct ccu_div _struct = { \
  129. .enable = _gate, \
  130. .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
  131. .common = { \
  132. .reg = _reg, \
  133. .hw.init = CLK_HW_INIT(_name, \
  134. _parent, \
  135. &ccu_div_ops, \
  136. _flags), \
  137. }, \
  138. }
  139. #define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth, \
  140. _flags) \
  141. SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
  142. _mshift, _mwidth, 0, _flags)
  143. static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
  144. {
  145. struct ccu_common *common = hw_to_ccu_common(hw);
  146. return container_of(common, struct ccu_div, common);
  147. }
  148. extern const struct clk_ops ccu_div_ops;
  149. #endif /* _CCU_DIV_H_ */