1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __MACH_MMP_CLK_H |
3 | #define __MACH_MMP_CLK_H |
4 | |
5 | #include <linux/clk-provider.h> |
6 | #include <linux/pm_domain.h> |
7 | #include <linux/clkdev.h> |
8 | |
9 | #define APBC_NO_BUS_CTRL BIT(0) |
10 | #define APBC_POWER_CTRL BIT(1) |
11 | |
12 | |
13 | /* Clock type "factor" */ |
14 | struct mmp_clk_factor_masks { |
15 | unsigned int factor; |
16 | unsigned int num_mask; |
17 | unsigned int den_mask; |
18 | unsigned int num_shift; |
19 | unsigned int den_shift; |
20 | unsigned int enable_mask; |
21 | }; |
22 | |
23 | struct mmp_clk_factor_tbl { |
24 | unsigned int num; |
25 | unsigned int den; |
26 | }; |
27 | |
28 | struct mmp_clk_factor { |
29 | struct clk_hw hw; |
30 | void __iomem *base; |
31 | struct mmp_clk_factor_masks *masks; |
32 | struct mmp_clk_factor_tbl *ftbl; |
33 | unsigned int ftbl_cnt; |
34 | spinlock_t *lock; |
35 | }; |
36 | |
37 | extern struct clk *mmp_clk_register_factor(const char *name, |
38 | const char *parent_name, unsigned long flags, |
39 | void __iomem *base, struct mmp_clk_factor_masks *masks, |
40 | struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt, |
41 | spinlock_t *lock); |
42 | |
43 | /* Clock type "mix" */ |
44 | #define MMP_CLK_BITS_MASK(width, shift) \ |
45 | (((1 << (width)) - 1) << (shift)) |
46 | #define MMP_CLK_BITS_GET_VAL(data, width, shift) \ |
47 | ((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift)) |
48 | #define MMP_CLK_BITS_SET_VAL(val, width, shift) \ |
49 | (((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift)) |
50 | |
51 | enum { |
52 | MMP_CLK_MIX_TYPE_V1, |
53 | MMP_CLK_MIX_TYPE_V2, |
54 | MMP_CLK_MIX_TYPE_V3, |
55 | }; |
56 | |
57 | /* The register layout */ |
58 | struct mmp_clk_mix_reg_info { |
59 | void __iomem *reg_clk_ctrl; |
60 | void __iomem *reg_clk_sel; |
61 | u8 width_div; |
62 | u8 shift_div; |
63 | u8 width_mux; |
64 | u8 shift_mux; |
65 | u8 bit_fc; |
66 | }; |
67 | |
68 | /* The suggested clock table from user. */ |
69 | struct mmp_clk_mix_clk_table { |
70 | unsigned long rate; |
71 | u8 parent_index; |
72 | unsigned int divisor; |
73 | unsigned int valid; |
74 | }; |
75 | |
76 | struct mmp_clk_mix_config { |
77 | struct mmp_clk_mix_reg_info reg_info; |
78 | struct mmp_clk_mix_clk_table *table; |
79 | unsigned int table_size; |
80 | u32 *mux_table; |
81 | struct clk_div_table *div_table; |
82 | u8 div_flags; |
83 | u8 mux_flags; |
84 | }; |
85 | |
86 | struct mmp_clk_mix { |
87 | struct clk_hw hw; |
88 | struct mmp_clk_mix_reg_info reg_info; |
89 | struct mmp_clk_mix_clk_table *table; |
90 | u32 *mux_table; |
91 | struct clk_div_table *div_table; |
92 | unsigned int table_size; |
93 | u8 div_flags; |
94 | u8 mux_flags; |
95 | unsigned int type; |
96 | spinlock_t *lock; |
97 | }; |
98 | |
99 | extern const struct clk_ops mmp_clk_mix_ops; |
100 | extern struct clk *mmp_clk_register_mix(struct device *dev, |
101 | const char *name, |
102 | const char * const *parent_names, |
103 | u8 num_parents, |
104 | unsigned long flags, |
105 | struct mmp_clk_mix_config *config, |
106 | spinlock_t *lock); |
107 | |
108 | |
109 | /* Clock type "gate". MMP private gate */ |
110 | #define MMP_CLK_GATE_NEED_DELAY BIT(0) |
111 | |
112 | struct mmp_clk_gate { |
113 | struct clk_hw hw; |
114 | void __iomem *reg; |
115 | u32 mask; |
116 | u32 val_enable; |
117 | u32 val_disable; |
118 | unsigned int flags; |
119 | spinlock_t *lock; |
120 | }; |
121 | |
122 | extern const struct clk_ops mmp_clk_gate_ops; |
123 | extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name, |
124 | const char *parent_name, unsigned long flags, |
125 | void __iomem *reg, u32 mask, u32 val_enable, |
126 | u32 val_disable, unsigned int gate_flags, |
127 | spinlock_t *lock); |
128 | |
129 | extern struct clk *mmp_clk_register_apbc(const char *name, |
130 | const char *parent_name, void __iomem *base, |
131 | unsigned int delay, unsigned int apbc_flags, spinlock_t *lock); |
132 | extern struct clk *mmp_clk_register_apmu(const char *name, |
133 | const char *parent_name, void __iomem *base, u32 enable_mask, |
134 | spinlock_t *lock); |
135 | |
136 | struct mmp_clk_unit { |
137 | unsigned int nr_clks; |
138 | struct clk **clk_table; |
139 | struct clk_onecell_data clk_data; |
140 | }; |
141 | |
142 | struct mmp_param_fixed_rate_clk { |
143 | unsigned int id; |
144 | char *name; |
145 | const char *parent_name; |
146 | unsigned long flags; |
147 | unsigned long fixed_rate; |
148 | }; |
149 | void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit, |
150 | struct mmp_param_fixed_rate_clk *clks, |
151 | int size); |
152 | |
153 | struct mmp_param_fixed_factor_clk { |
154 | unsigned int id; |
155 | char *name; |
156 | const char *parent_name; |
157 | unsigned long mult; |
158 | unsigned long div; |
159 | unsigned long flags; |
160 | }; |
161 | void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit, |
162 | struct mmp_param_fixed_factor_clk *clks, |
163 | int size); |
164 | |
165 | struct mmp_param_general_gate_clk { |
166 | unsigned int id; |
167 | const char *name; |
168 | const char *parent_name; |
169 | unsigned long flags; |
170 | unsigned long offset; |
171 | u8 bit_idx; |
172 | u8 gate_flags; |
173 | spinlock_t *lock; |
174 | }; |
175 | void mmp_register_general_gate_clks(struct mmp_clk_unit *unit, |
176 | struct mmp_param_general_gate_clk *clks, |
177 | void __iomem *base, int size); |
178 | |
179 | struct mmp_param_gate_clk { |
180 | unsigned int id; |
181 | char *name; |
182 | const char *parent_name; |
183 | unsigned long flags; |
184 | unsigned long offset; |
185 | u32 mask; |
186 | u32 val_enable; |
187 | u32 val_disable; |
188 | unsigned int gate_flags; |
189 | spinlock_t *lock; |
190 | }; |
191 | void mmp_register_gate_clks(struct mmp_clk_unit *unit, |
192 | struct mmp_param_gate_clk *clks, |
193 | void __iomem *base, int size); |
194 | |
195 | struct mmp_param_mux_clk { |
196 | unsigned int id; |
197 | char *name; |
198 | const char * const *parent_name; |
199 | u8 num_parents; |
200 | unsigned long flags; |
201 | unsigned long offset; |
202 | u8 shift; |
203 | u8 width; |
204 | u8 mux_flags; |
205 | spinlock_t *lock; |
206 | }; |
207 | void mmp_register_mux_clks(struct mmp_clk_unit *unit, |
208 | struct mmp_param_mux_clk *clks, |
209 | void __iomem *base, int size); |
210 | |
211 | struct mmp_param_div_clk { |
212 | unsigned int id; |
213 | char *name; |
214 | const char *parent_name; |
215 | unsigned long flags; |
216 | unsigned long offset; |
217 | u8 shift; |
218 | u8 width; |
219 | u8 div_flags; |
220 | spinlock_t *lock; |
221 | }; |
222 | void mmp_register_div_clks(struct mmp_clk_unit *unit, |
223 | struct mmp_param_div_clk *clks, |
224 | void __iomem *base, int size); |
225 | |
226 | struct mmp_param_pll_clk { |
227 | unsigned int id; |
228 | char *name; |
229 | unsigned long default_rate; |
230 | unsigned long enable_offset; |
231 | u32 enable; |
232 | unsigned long offset; |
233 | u8 shift; |
234 | /* MMP3 specific: */ |
235 | unsigned long input_rate; |
236 | unsigned long postdiv_offset; |
237 | unsigned long postdiv_shift; |
238 | }; |
239 | void mmp_register_pll_clks(struct mmp_clk_unit *unit, |
240 | struct mmp_param_pll_clk *clks, |
241 | void __iomem *base, int size); |
242 | |
243 | #define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \ |
244 | { \ |
245 | .width_div = (w_d), \ |
246 | .shift_div = (s_d), \ |
247 | .width_mux = (w_m), \ |
248 | .shift_mux = (s_m), \ |
249 | .bit_fc = (fc), \ |
250 | } |
251 | |
252 | void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, |
253 | int nr_clks); |
254 | void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, |
255 | struct clk *clk); |
256 | |
257 | /* Power islands */ |
258 | #define MMP_PM_DOMAIN_NO_DISABLE BIT(0) |
259 | |
260 | struct generic_pm_domain *mmp_pm_domain_register(const char *name, |
261 | void __iomem *reg, |
262 | u32 power_on, u32 reset, u32 clock_enable, |
263 | unsigned int flags, spinlock_t *lock); |
264 | |
265 | #endif |
266 | |