ccu_mux.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _CCU_MUX_H_
  3. #define _CCU_MUX_H_
  4. #include <linux/clk-provider.h>
  5. #include "ccu_common.h"
  6. struct ccu_mux_fixed_prediv {
  7. u8 index;
  8. u16 div;
  9. };
  10. struct ccu_mux_var_prediv {
  11. u8 index;
  12. u8 shift;
  13. u8 width;
  14. };
  15. struct ccu_mux_internal {
  16. u8 shift;
  17. u8 width;
  18. const u8 *table;
  19. const struct ccu_mux_fixed_prediv *fixed_predivs;
  20. u8 n_predivs;
  21. const struct ccu_mux_var_prediv *var_predivs;
  22. u8 n_var_predivs;
  23. };
  24. #define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table) \
  25. { \
  26. .shift = _shift, \
  27. .width = _width, \
  28. .table = _table, \
  29. }
  30. #define _SUNXI_CCU_MUX(_shift, _width) \
  31. _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL)
  32. struct ccu_mux {
  33. u16 reg;
  34. u32 enable;
  35. struct ccu_mux_internal mux;
  36. struct ccu_common common;
  37. };
  38. #define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table, \
  39. _reg, _shift, _width, _gate, \
  40. _flags) \
  41. struct ccu_mux _struct = { \
  42. .enable = _gate, \
  43. .mux = _SUNXI_CCU_MUX_TABLE(_shift, _width, _table), \
  44. .common = { \
  45. .reg = _reg, \
  46. .hw.init = CLK_HW_INIT_PARENTS(_name, \
  47. _parents, \
  48. &ccu_mux_ops, \
  49. _flags), \
  50. } \
  51. }
  52. #define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \
  53. _shift, _width, _gate, _flags) \
  54. SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
  55. _reg, _shift, _width, _gate, \
  56. _flags)
  57. #define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, \
  58. _flags) \
  59. SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
  60. _reg, _shift, _width, 0, _flags)
  61. static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
  62. {
  63. struct ccu_common *common = hw_to_ccu_common(hw);
  64. return container_of(common, struct ccu_mux, common);
  65. }
  66. extern const struct clk_ops ccu_mux_ops;
  67. unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
  68. struct ccu_mux_internal *cm,
  69. int parent_index,
  70. unsigned long parent_rate);
  71. int ccu_mux_helper_determine_rate(struct ccu_common *common,
  72. struct ccu_mux_internal *cm,
  73. struct clk_rate_request *req,
  74. unsigned long (*round)(struct ccu_mux_internal *,
  75. struct clk_hw *,
  76. unsigned long *,
  77. unsigned long,
  78. void *),
  79. void *data);
  80. u8 ccu_mux_helper_get_parent(struct ccu_common *common,
  81. struct ccu_mux_internal *cm);
  82. int ccu_mux_helper_set_parent(struct ccu_common *common,
  83. struct ccu_mux_internal *cm,
  84. u8 index);
  85. struct ccu_mux_nb {
  86. struct notifier_block clk_nb;
  87. struct ccu_common *common;
  88. struct ccu_mux_internal *cm;
  89. u32 delay_us; /* How many us to wait after reparenting */
  90. u8 bypass_index; /* Which parent to temporarily use */
  91. u8 original_index; /* This is set by the notifier callback */
  92. };
  93. #define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb)
  94. int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb);
  95. #endif /* _CCU_MUX_H_ */