1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * drivers/clk/at91/pmc.h |
4 | * |
5 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> |
6 | */ |
7 | |
8 | #ifndef __PMC_H_ |
9 | #define __PMC_H_ |
10 | |
11 | #include <linux/io.h> |
12 | #include <linux/irqdomain.h> |
13 | #include <linux/regmap.h> |
14 | #include <linux/spinlock.h> |
15 | |
16 | #include <dt-bindings/clock/at91.h> |
17 | |
18 | extern spinlock_t pmc_pcr_lock; |
19 | |
20 | struct pmc_data { |
21 | unsigned int ncore; |
22 | struct clk_hw **chws; |
23 | unsigned int nsystem; |
24 | struct clk_hw **shws; |
25 | unsigned int nperiph; |
26 | struct clk_hw **phws; |
27 | unsigned int ngck; |
28 | struct clk_hw **ghws; |
29 | unsigned int npck; |
30 | struct clk_hw **pchws; |
31 | |
32 | struct clk_hw *hwtable[]; |
33 | }; |
34 | |
35 | struct clk_range { |
36 | unsigned long min; |
37 | unsigned long max; |
38 | }; |
39 | |
40 | #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,} |
41 | |
42 | struct clk_master_layout { |
43 | u32 offset; |
44 | u32 mask; |
45 | u8 pres_shift; |
46 | }; |
47 | |
48 | extern const struct clk_master_layout at91rm9200_master_layout; |
49 | extern const struct clk_master_layout at91sam9x5_master_layout; |
50 | |
51 | struct clk_master_characteristics { |
52 | struct clk_range output; |
53 | u32 divisors[5]; |
54 | u8 have_div3_pres; |
55 | }; |
56 | |
57 | struct clk_pll_layout { |
58 | u32 pllr_mask; |
59 | u32 mul_mask; |
60 | u32 frac_mask; |
61 | u32 div_mask; |
62 | u32 endiv_mask; |
63 | u8 mul_shift; |
64 | u8 frac_shift; |
65 | u8 div_shift; |
66 | u8 endiv_shift; |
67 | }; |
68 | |
69 | extern const struct clk_pll_layout at91rm9200_pll_layout; |
70 | extern const struct clk_pll_layout at91sam9g45_pll_layout; |
71 | extern const struct clk_pll_layout at91sam9g20_pllb_layout; |
72 | extern const struct clk_pll_layout sama5d3_pll_layout; |
73 | |
74 | struct clk_pll_characteristics { |
75 | struct clk_range input; |
76 | int num_output; |
77 | const struct clk_range *output; |
78 | u16 *icpll; |
79 | u8 *out; |
80 | u8 upll : 1; |
81 | }; |
82 | |
83 | struct clk_programmable_layout { |
84 | u8 pres_mask; |
85 | u8 pres_shift; |
86 | u8 css_mask; |
87 | u8 have_slck_mck; |
88 | u8 is_pres_direct; |
89 | }; |
90 | |
91 | extern const struct clk_programmable_layout at91rm9200_programmable_layout; |
92 | extern const struct clk_programmable_layout at91sam9g45_programmable_layout; |
93 | extern const struct clk_programmable_layout at91sam9x5_programmable_layout; |
94 | |
95 | struct clk_pcr_layout { |
96 | u32 offset; |
97 | u32 cmd; |
98 | u32 div_mask; |
99 | u32 gckcss_mask; |
100 | u32 pid_mask; |
101 | }; |
102 | |
103 | /** |
104 | * struct at91_clk_pms - Power management state for AT91 clock |
105 | * @rate: clock rate |
106 | * @parent_rate: clock parent rate |
107 | * @status: clock status (enabled or disabled) |
108 | * @parent: clock parent index |
109 | */ |
110 | struct at91_clk_pms { |
111 | unsigned long rate; |
112 | unsigned long parent_rate; |
113 | unsigned int status; |
114 | unsigned int parent; |
115 | }; |
116 | |
117 | #define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) |
118 | #define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) |
119 | |
120 | #define ndck(a, s) (a[s - 1].id + 1) |
121 | #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1) |
122 | struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, |
123 | unsigned int nperiph, unsigned int ngck, |
124 | unsigned int npck); |
125 | |
126 | int of_at91_get_clk_range(struct device_node *np, const char *propname, |
127 | struct clk_range *range); |
128 | |
129 | struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data); |
130 | |
131 | struct clk_hw * __init |
132 | at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name, |
133 | const char *parent_name); |
134 | |
135 | struct clk_hw * __init |
136 | at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name, |
137 | const char *parent_name); |
138 | |
139 | struct clk_hw * __init |
140 | at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name, |
141 | const char *parent_name); |
142 | |
143 | struct clk_hw * __init |
144 | at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, |
145 | const struct clk_pcr_layout *layout, |
146 | const char *name, const char **parent_names, |
147 | struct clk_hw **parent_hws, u32 *mux_table, |
148 | u8 num_parents, u8 id, |
149 | const struct clk_range *range, int chg_pid); |
150 | |
151 | struct clk_hw * __init |
152 | at91_clk_register_h32mx(struct regmap *regmap, const char *name, |
153 | const char *parent_name); |
154 | |
155 | struct clk_hw * __init |
156 | at91_clk_i2s_mux_register(struct regmap *regmap, const char *name, |
157 | const char * const *parent_names, |
158 | unsigned int num_parents, u8 bus_id); |
159 | |
160 | struct clk_hw * __init |
161 | at91_clk_register_main_rc_osc(struct regmap *regmap, const char *name, |
162 | u32 frequency, u32 accuracy); |
163 | struct clk_hw * __init |
164 | at91_clk_register_main_osc(struct regmap *regmap, const char *name, |
165 | const char *parent_name, |
166 | struct clk_parent_data *parent_data, bool bypass); |
167 | struct clk_hw * __init |
168 | at91_clk_register_rm9200_main(struct regmap *regmap, |
169 | const char *name, |
170 | const char *parent_name, |
171 | struct clk_hw *parent_hw); |
172 | struct clk_hw * __init |
173 | at91_clk_register_sam9x5_main(struct regmap *regmap, const char *name, |
174 | const char **parent_names, |
175 | struct clk_hw **parent_hws, int num_parents); |
176 | |
177 | struct clk_hw * __init |
178 | at91_clk_register_master_pres(struct regmap *regmap, const char *name, |
179 | int num_parents, const char **parent_names, |
180 | struct clk_hw **parent_hws, |
181 | const struct clk_master_layout *layout, |
182 | const struct clk_master_characteristics *characteristics, |
183 | spinlock_t *lock); |
184 | |
185 | struct clk_hw * __init |
186 | at91_clk_register_master_div(struct regmap *regmap, const char *name, |
187 | const char *parent_names, struct clk_hw *parent_hw, |
188 | const struct clk_master_layout *layout, |
189 | const struct clk_master_characteristics *characteristics, |
190 | spinlock_t *lock, u32 flags, u32 safe_div); |
191 | |
192 | struct clk_hw * __init |
193 | at91_clk_sama7g5_register_master(struct regmap *regmap, |
194 | const char *name, int num_parents, |
195 | const char **parent_names, |
196 | struct clk_hw **parent_hws, u32 *mux_table, |
197 | spinlock_t *lock, u8 id, bool critical, |
198 | int chg_pid); |
199 | |
200 | struct clk_hw * __init |
201 | at91_clk_register_peripheral(struct regmap *regmap, const char *name, |
202 | const char *parent_name, struct clk_hw *parent_hw, |
203 | u32 id); |
204 | struct clk_hw * __init |
205 | at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, |
206 | const struct clk_pcr_layout *layout, |
207 | const char *name, const char *parent_name, |
208 | struct clk_hw *parent_hw, |
209 | u32 id, const struct clk_range *range, |
210 | int chg_pid, unsigned long flags); |
211 | |
212 | struct clk_hw * __init |
213 | at91_clk_register_pll(struct regmap *regmap, const char *name, |
214 | const char *parent_name, u8 id, |
215 | const struct clk_pll_layout *layout, |
216 | const struct clk_pll_characteristics *characteristics); |
217 | struct clk_hw * __init |
218 | at91_clk_register_plldiv(struct regmap *regmap, const char *name, |
219 | const char *parent_name); |
220 | |
221 | struct clk_hw * __init |
222 | sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, |
223 | const char *name, const char *parent_name, |
224 | struct clk_hw *parent_hw, u8 id, |
225 | const struct clk_pll_characteristics *characteristics, |
226 | const struct clk_pll_layout *layout, u32 flags, |
227 | u32 safe_div); |
228 | |
229 | struct clk_hw * __init |
230 | sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, |
231 | const char *name, const char *parent_name, |
232 | struct clk_hw *parent_hw, u8 id, |
233 | const struct clk_pll_characteristics *characteristics, |
234 | const struct clk_pll_layout *layout, u32 flags); |
235 | |
236 | struct clk_hw * __init |
237 | at91_clk_register_programmable(struct regmap *regmap, const char *name, |
238 | const char **parent_names, struct clk_hw **parent_hws, |
239 | u8 num_parents, u8 id, |
240 | const struct clk_programmable_layout *layout, |
241 | u32 *mux_table); |
242 | |
243 | struct clk_hw * __init |
244 | at91_clk_register_sam9260_slow(struct regmap *regmap, |
245 | const char *name, |
246 | const char **parent_names, |
247 | int num_parents); |
248 | |
249 | struct clk_hw * __init |
250 | at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name, |
251 | const char **parent_names, u8 num_parents); |
252 | |
253 | struct clk_hw * __init |
254 | at91_clk_register_system(struct regmap *regmap, const char *name, |
255 | const char *parent_name, struct clk_hw *parent_hw, |
256 | u8 id, unsigned long flags); |
257 | |
258 | struct clk_hw * __init |
259 | at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, |
260 | const char **parent_names, u8 num_parents); |
261 | struct clk_hw * __init |
262 | at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, |
263 | const char *parent_name); |
264 | struct clk_hw * __init |
265 | sam9x60_clk_register_usb(struct regmap *regmap, const char *name, |
266 | const char **parent_names, u8 num_parents); |
267 | struct clk_hw * __init |
268 | at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, |
269 | const char *parent_name, const u32 *divisors); |
270 | |
271 | struct clk_hw * __init |
272 | at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr, |
273 | const char *name, const char *parent_name, |
274 | struct clk_hw *parent_hw); |
275 | |
276 | struct clk_hw * __init |
277 | at91_clk_sama7g5_register_utmi(struct regmap *regmap, const char *name, |
278 | const char *parent_name, struct clk_hw *parent_hw); |
279 | |
280 | #endif /* __PMC_H_ */ |
281 | |