clk-mux.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (c) 2018 MediaTek Inc.
  4. * Author: Owen Chen <owen.chen@mediatek.com>
  5. */
  6. #ifndef __DRV_CLK_MTK_MUX_H
  7. #define __DRV_CLK_MTK_MUX_H
  8. #include <linux/notifier.h>
  9. #include <linux/spinlock.h>
  10. #include <linux/types.h>
  11. struct clk;
  12. struct clk_hw_onecell_data;
  13. struct clk_ops;
  14. struct device;
  15. struct device_node;
  16. struct mtk_mux {
  17. int id;
  18. const char *name;
  19. const char * const *parent_names;
  20. const u8 *parent_index;
  21. unsigned int flags;
  22. u32 mux_ofs;
  23. u32 set_ofs;
  24. u32 clr_ofs;
  25. u32 upd_ofs;
  26. u8 mux_shift;
  27. u8 mux_width;
  28. u8 gate_shift;
  29. s8 upd_shift;
  30. const struct clk_ops *ops;
  31. signed char num_parents;
  32. };
  33. #define __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \
  34. _num_parents, _mux_ofs, _mux_set_ofs, \
  35. _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, \
  36. _upd, _flags, _ops) { \
  37. .id = _id, \
  38. .name = _name, \
  39. .mux_ofs = _mux_ofs, \
  40. .set_ofs = _mux_set_ofs, \
  41. .clr_ofs = _mux_clr_ofs, \
  42. .upd_ofs = _upd_ofs, \
  43. .mux_shift = _shift, \
  44. .mux_width = _width, \
  45. .gate_shift = _gate, \
  46. .upd_shift = _upd, \
  47. .parent_names = _parents, \
  48. .parent_index = _paridx, \
  49. .num_parents = _num_parents, \
  50. .flags = _flags, \
  51. .ops = &_ops, \
  52. }
  53. #define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
  54. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  55. _gate, _upd_ofs, _upd, _flags, _ops) \
  56. __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  57. NULL, ARRAY_SIZE(_parents), _mux_ofs, \
  58. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  59. _gate, _upd_ofs, _upd, _flags, _ops) \
  60. #define GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, _paridx, \
  61. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
  62. _width, _gate, _upd_ofs, _upd, _flags, _ops) \
  63. __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  64. _paridx, ARRAY_SIZE(_paridx), _mux_ofs, \
  65. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  66. _gate, _upd_ofs, _upd, _flags, _ops) \
  67. extern const struct clk_ops mtk_mux_clr_set_upd_ops;
  68. extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
  69. #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
  70. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  71. _gate, _upd_ofs, _upd, _flags) \
  72. GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
  73. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  74. _gate, _upd_ofs, _upd, _flags, \
  75. mtk_mux_gate_clr_set_upd_ops)
  76. #define MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, \
  77. _paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  78. _shift, _width, _gate, _upd_ofs, _upd, _flags) \
  79. GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, \
  80. _paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  81. _shift, _width, _gate, _upd_ofs, _upd, _flags, \
  82. mtk_mux_gate_clr_set_upd_ops)
  83. #define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
  84. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  85. _gate, _upd_ofs, _upd) \
  86. MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  87. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
  88. _width, _gate, _upd_ofs, _upd, \
  89. CLK_SET_RATE_PARENT)
  90. #define MUX_GATE_CLR_SET_UPD_INDEXED(_id, _name, _parents, _paridx, \
  91. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
  92. _width, _gate, _upd_ofs, _upd) \
  93. MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, \
  94. _parents, _paridx, _mux_ofs, _mux_set_ofs, \
  95. _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, \
  96. _upd, CLK_SET_RATE_PARENT)
  97. #define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
  98. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  99. _upd_ofs, _upd) \
  100. GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
  101. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  102. 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \
  103. mtk_mux_clr_set_upd_ops)
  104. int mtk_clk_register_muxes(struct device *dev,
  105. const struct mtk_mux *muxes,
  106. int num, struct device_node *node,
  107. spinlock_t *lock,
  108. struct clk_hw_onecell_data *clk_data);
  109. void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
  110. struct clk_hw_onecell_data *clk_data);
  111. struct mtk_mux_nb {
  112. struct notifier_block nb;
  113. const struct clk_ops *ops;
  114. u8 bypass_index; /* Which parent to temporarily use */
  115. u8 original_index; /* Set by notifier callback */
  116. };
  117. #define to_mtk_mux_nb(_nb) container_of(_nb, struct mtk_mux_nb, nb)
  118. int devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk,
  119. struct mtk_mux_nb *mux_nb);
  120. #endif /* __DRV_CLK_MTK_MUX_H */