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