ccu_mux.h 2.8 KB

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