1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _CCU_MUX_H_
3 #define _CCU_MUX_H_
4
5 #include "ccu.h"
6 #include "ccu_common.h"
7
8 /*
9 * Create a contiguous bitmask starting at bit position @l and ending at
10 * position @h. For example
11 * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
12 */
13
14 struct ccu_mux_fixed_prediv
15 {
16 u8 index;
17 u16 div;
18 };
19
20 struct ccu_mux_var_prediv
21 {
22 u8 index;
23 u8 shift;
24 u8 width;
25 };
26
27 struct ccu_mux_internal
28 {
29 u8 shift;
30 u8 width;
31 const u8 *table;
32
33 const struct ccu_mux_fixed_prediv *fixed_predivs;
34 u8 n_predivs;
35
36 const struct ccu_mux_var_prediv *var_predivs;
37 u8 n_var_predivs;
38 };
39
40 #define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table) \
41 { \
42 .shift = _shift, \
43 .width = _width, \
44 .table = _table, \
45 }
46
47 #define _SUNXI_CCU_MUX(_shift, _width) \
48 _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL)
49
50 struct ccu_mux
51 {
52 u32 reg;
53 u32 enable;
54
55 struct ccu_mux_internal mux;
56 struct ccu_common common;
57 };
58
59 #define SUNXI_CCU_MUX_WITH_GATE_KEY(_struct, _name, _parents, \
60 _reg, _shift, _width, \
61 _key_value, _gate, _flags) \
62 struct ccu_mux _struct = { \
63 .enable = _gate, \
64 .mux = _SUNXI_CCU_MUX(_shift, _width), \
65 .common = { \
66 .reg = _reg, \
67 .features = CCU_FEATURE_KEY_FIELD_MOD, \
68 .key_value = _key_value, \
69 .hw.init = CLK_HW_INIT_PARENTS(_name, \
70 _parents, \
71 &ccu_mux_ops, \
72 _flags), \
73 } \
74 }
75
76 #define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table, \
77 _reg, _shift, _width, _gate, \
78 _flags) \
79 struct ccu_mux _struct = { \
80 .enable = _gate, \
81 .mux = _SUNXI_CCU_MUX_TABLE(_shift, _width, _table), \
82 .common = { \
83 .reg = _reg, \
84 .hw.init = CLK_HW_INIT_PARENTS(_name, \
85 _parents, \
86 &ccu_mux_ops, \
87 _flags), \
88 } \
89 }
90
91 #define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \
92 _shift, _width, _gate, _flags) \
93 SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
94 _reg, _shift, _width, _gate, \
95 _flags)
96
97 #define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, \
98 _flags) \
99 SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
100 _reg, _shift, _width, 0, _flags)
101
hw_to_ccu_mux(struct clk_hw * hw)102 static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
103 {
104 struct ccu_common *common = hw_to_ccu_common(hw);
105
106 return container_of(common, struct ccu_mux, common);
107 }
108
109 extern const struct clk_ops ccu_mux_ops;
110
111 unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
112 struct ccu_mux_internal *cm,
113 int parent_index,
114 unsigned long parent_rate);
115 int ccu_mux_helper_determine_rate(struct ccu_common *common,
116 struct ccu_mux_internal *cm,
117 struct clk_rate_request *req,
118 unsigned long (*round)(struct ccu_mux_internal *,
119 struct clk_hw *,
120 unsigned long *,
121 unsigned long,
122 void *),
123 void *data);
124 u8 ccu_mux_helper_get_parent(struct ccu_common *common,
125 struct ccu_mux_internal *cm);
126 int ccu_mux_helper_set_parent(struct ccu_common *common,
127 struct ccu_mux_internal *cm,
128 u8 index);
129
130 #endif /* _CCU_MUX_H_ */
131