blob: 809d05f70fdf854bc244a97e12b410e1fb8d05bd [file] [log] [blame]
Gabriel Fernandez1308d752020-03-11 11:30:34 +01001/*
2 * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
5 */
6
7#ifndef CLK_STM32_CORE_H
8#define CLK_STM32_CORE_H
9
10struct mux_cfg {
11 uint16_t offset;
12 uint8_t shift;
13 uint8_t width;
14 uint8_t bitrdy;
15};
16
17struct gate_cfg {
18 uint16_t offset;
19 uint8_t bit_idx;
20 uint8_t set_clr;
21};
22
23struct clk_div_table {
24 unsigned int val;
25 unsigned int div;
26};
27
28struct div_cfg {
29 uint16_t offset;
30 uint8_t shift;
31 uint8_t width;
32 uint8_t flags;
33 uint8_t bitrdy;
34 const struct clk_div_table *table;
35};
36
37struct parent_cfg {
38 uint8_t num_parents;
39 const uint16_t *id_parents;
40 struct mux_cfg *mux;
41};
42
43struct stm32_clk_priv;
44
45struct stm32_clk_ops {
46 unsigned long (*recalc_rate)(struct stm32_clk_priv *priv, int id, unsigned long rate);
47 int (*get_parent)(struct stm32_clk_priv *priv, int id);
48 int (*set_rate)(struct stm32_clk_priv *priv, int id, unsigned long rate,
49 unsigned long prate);
50 int (*enable)(struct stm32_clk_priv *priv, int id);
51 void (*disable)(struct stm32_clk_priv *priv, int id);
52 bool (*is_enabled)(struct stm32_clk_priv *priv, int id);
53 void (*init)(struct stm32_clk_priv *priv, int id);
54};
55
56struct clk_stm32 {
57 const char *name;
58 uint16_t binding;
59 uint16_t parent;
60 uint8_t flags;
61 void *clock_cfg;
62 const struct stm32_clk_ops *ops;
63};
64
65struct stm32_clk_priv {
66 uintptr_t base;
67 const uint32_t num;
68 const struct clk_stm32 *clks;
69 const struct parent_cfg *parents;
70 const uint32_t nb_parents;
71 const struct gate_cfg *gates;
72 const uint32_t nb_gates;
73 const struct div_cfg *div;
74 const uint32_t nb_div;
75 struct clk_oscillator_data *osci_data;
76 const uint32_t nb_osci_data;
77 uint32_t *gate_refcounts;
78 void *pdata;
79};
80
81struct stm32_clk_bypass {
82 uint16_t offset;
83 uint8_t bit_byp;
84 uint8_t bit_digbyp;
85};
86
87struct stm32_clk_css {
88 uint16_t offset;
89 uint8_t bit_css;
90};
91
92struct stm32_clk_drive {
93 uint16_t offset;
94 uint8_t drv_shift;
95 uint8_t drv_width;
96 uint8_t drv_default;
97};
98
99struct clk_oscillator_data {
100 const char *name;
101 uint16_t id_clk;
102 unsigned long frequency;
103 uint16_t gate_id;
104 uint16_t gate_rdy_id;
105 struct stm32_clk_bypass *bypass;
106 struct stm32_clk_css *css;
107 struct stm32_clk_drive *drive;
108};
109
110struct clk_fixed_rate {
111 const char *name;
112 unsigned long fixed_rate;
113};
114
115struct clk_gate_cfg {
116 uint32_t offset;
117 uint8_t bit_idx;
118};
119
120/* CLOCK FLAGS */
121#define CLK_IS_CRITICAL BIT(0)
122#define CLK_IGNORE_UNUSED BIT(1)
123#define CLK_SET_RATE_PARENT BIT(2)
124
125#define CLK_DIVIDER_ONE_BASED BIT(0)
126#define CLK_DIVIDER_POWER_OF_TWO BIT(1)
127#define CLK_DIVIDER_ALLOW_ZERO BIT(2)
128#define CLK_DIVIDER_HIWORD_MASK BIT(3)
129#define CLK_DIVIDER_ROUND_CLOSEST BIT(4)
130#define CLK_DIVIDER_READ_ONLY BIT(5)
131#define CLK_DIVIDER_MAX_AT_ZERO BIT(6)
132#define CLK_DIVIDER_BIG_ENDIAN BIT(7)
133
134#define MUX_MAX_PARENTS U(0x8000)
135#define MUX_PARENT_MASK GENMASK(14, 0)
136#define MUX_FLAG U(0x8000)
137#define MUX(mux) ((mux) | MUX_FLAG)
138
139#define NO_GATE 0
140#define _NO_ID UINT16_MAX
141#define CLK_IS_ROOT UINT16_MAX
142#define MUX_NO_BIT_RDY UINT8_MAX
143#define DIV_NO_BIT_RDY UINT8_MAX
144
145#define MASK_WIDTH_SHIFT(_width, _shift) \
146 GENMASK(((_width) + (_shift) - 1U), (_shift))
147
148int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base);
149void clk_stm32_enable_critical_clocks(void);
150
151struct stm32_clk_priv *clk_stm32_get_priv(void);
152
153int clk_get_index(struct stm32_clk_priv *priv, unsigned long binding_id);
154const struct clk_stm32 *_clk_get(struct stm32_clk_priv *priv, int id);
155
156void clk_oscillator_set_bypass(struct stm32_clk_priv *priv, int id, bool digbyp, bool bypass);
157void clk_oscillator_set_drive(struct stm32_clk_priv *priv, int id, uint8_t lsedrv);
158void clk_oscillator_set_css(struct stm32_clk_priv *priv, int id, bool css);
159
160int _clk_stm32_gate_wait_ready(struct stm32_clk_priv *priv, uint16_t gate_id, bool ready_on);
161
162int clk_oscillator_wait_ready(struct stm32_clk_priv *priv, int id, bool ready_on);
163int clk_oscillator_wait_ready_on(struct stm32_clk_priv *priv, int id);
164int clk_oscillator_wait_ready_off(struct stm32_clk_priv *priv, int id);
165
166const char *_clk_stm32_get_name(struct stm32_clk_priv *priv, int id);
167const char *clk_stm32_get_name(struct stm32_clk_priv *priv, unsigned long binding_id);
168int clk_stm32_get_counter(unsigned long binding_id);
169
170void _clk_stm32_gate_disable(struct stm32_clk_priv *priv, uint16_t gate_id);
171int _clk_stm32_gate_enable(struct stm32_clk_priv *priv, uint16_t gate_id);
172
173int _clk_stm32_set_parent(struct stm32_clk_priv *priv, int id, int src_id);
174int _clk_stm32_set_parent_by_index(struct stm32_clk_priv *priv, int clk, int sel);
175
176int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int id);
177int _clk_stm32_get_parent_by_index(struct stm32_clk_priv *priv, int clk_id, int idx);
178int _clk_stm32_get_parent_index(struct stm32_clk_priv *priv, int clk_id);
179
180unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id);
181unsigned long _clk_stm32_get_parent_rate(struct stm32_clk_priv *priv, int id);
182
183bool _stm32_clk_is_flags(struct stm32_clk_priv *priv, int id, uint8_t flag);
184
185int _clk_stm32_enable(struct stm32_clk_priv *priv, int id);
186void _clk_stm32_disable(struct stm32_clk_priv *priv, int id);
187
188int clk_stm32_enable_call_ops(struct stm32_clk_priv *priv, uint16_t id);
189void clk_stm32_disable_call_ops(struct stm32_clk_priv *priv, uint16_t id);
190
191bool _clk_stm32_is_enabled(struct stm32_clk_priv *priv, int id);
192
193int _clk_stm32_divider_set_rate(struct stm32_clk_priv *priv, int div_id,
194 unsigned long rate, unsigned long parent_rate);
195
196int clk_stm32_divider_set_rate(struct stm32_clk_priv *priv, int id, unsigned long rate,
197 unsigned long prate);
198
199unsigned long _clk_stm32_divider_recalc(struct stm32_clk_priv *priv,
200 int div_id,
201 unsigned long prate);
202
203unsigned long clk_stm32_divider_recalc(struct stm32_clk_priv *priv, int idx,
204 unsigned long prate);
205
206int clk_stm32_gate_enable(struct stm32_clk_priv *priv, int idx);
207void clk_stm32_gate_disable(struct stm32_clk_priv *priv, int idx);
208
209bool _clk_stm32_gate_is_enabled(struct stm32_clk_priv *priv, int gate_id);
210bool clk_stm32_gate_is_enabled(struct stm32_clk_priv *priv, int idx);
211
212uint32_t clk_stm32_div_get_value(struct stm32_clk_priv *priv, int div_id);
213int clk_stm32_set_div(struct stm32_clk_priv *priv, uint32_t div_id, uint32_t value);
214int clk_mux_set_parent(struct stm32_clk_priv *priv, uint16_t pid, uint8_t sel);
215int clk_mux_get_parent(struct stm32_clk_priv *priv, uint32_t mux_id);
216
217int stm32_clk_parse_fdt_by_name(void *fdt, int node, const char *name, uint32_t *tab, uint32_t *nb);
218
219#ifdef CFG_STM32_CLK_DEBUG
220void clk_stm32_display_clock_info(void);
221#endif
222
223struct clk_stm32_div_cfg {
224 int id;
225};
226
227#define STM32_DIV(idx, _binding, _parent, _flags, _div_id) \
228 [(idx)] = (struct clk_stm32){ \
229 .name = #idx,\
230 .binding = (_binding),\
231 .parent = (_parent),\
232 .flags = (_flags),\
233 .clock_cfg = &(struct clk_stm32_div_cfg){\
234 .id = (_div_id),\
235 },\
236 .ops = &clk_stm32_divider_ops,\
237 }
238
239struct clk_stm32_gate_cfg {
240 int id;
241};
242
243#define STM32_GATE(idx, _binding, _parent, _flags, _gate_id) \
244 [(idx)] = (struct clk_stm32){ \
245 .name = #idx,\
246 .binding = (_binding),\
247 .parent = (_parent),\
248 .flags = (_flags),\
249 .clock_cfg = &(struct clk_stm32_gate_cfg){\
250 .id = (_gate_id),\
251 },\
252 .ops = &clk_stm32_gate_ops,\
253 }
254
255struct fixed_factor_cfg {
256 unsigned int mult;
257 unsigned int div;
258};
259
260unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
261 int _idx, unsigned long prate);
262
263#define FIXED_FACTOR(idx, _idx, _parent, _mult, _div) \
264 [(idx)] = (struct clk_stm32){ \
265 .name = #idx,\
266 .binding = (_idx),\
267 .parent = (_parent),\
268 .clock_cfg = &(struct fixed_factor_cfg){\
269 .mult = (_mult),\
270 .div = (_div),\
271 },\
272 .ops = &clk_fixed_factor_ops,\
273 }
274
275#define GATE(idx, _binding, _parent, _flags, _offset, _bit_idx) \
276 [(idx)] = (struct clk_stm32){ \
277 .name = #idx,\
278 .binding = (_binding),\
279 .parent = (_parent),\
280 .flags = (_flags),\
281 .clock_cfg = &(struct clk_gate_cfg){\
282 .offset = (_offset),\
283 .bit_idx = (_bit_idx),\
284 },\
285 .ops = &clk_gate_ops,\
286 }
287
288#define STM32_MUX(idx, _binding, _mux_id, _flags) \
289 [(idx)] = (struct clk_stm32){ \
290 .name = #idx,\
291 .binding = (_binding),\
292 .parent = (MUX(_mux_id)),\
293 .flags = (_flags),\
294 .clock_cfg = NULL,\
295 .ops = (&clk_mux_ops),\
296 }
297
298struct clk_timer_cfg {
299 uint32_t apbdiv;
300 uint32_t timpre;
301};
302
303#define CK_TIMER(idx, _idx, _parent, _flags, _apbdiv, _timpre) \
304 [(idx)] = (struct clk_stm32){ \
305 .name = #idx,\
306 .binding = (_idx),\
307 .parent = (_parent),\
308 .flags = (CLK_SET_RATE_PARENT | (_flags)),\
309 .clock_cfg = &(struct clk_timer_cfg){\
310 .apbdiv = (_apbdiv),\
311 .timpre = (_timpre),\
312 },\
313 .ops = &clk_timer_ops,\
314 }
315
316struct clk_stm32_fixed_rate_cfg {
317 unsigned long rate;
318};
319
320#define CLK_FIXED_RATE(idx, _binding, _rate) \
321 [(idx)] = (struct clk_stm32){ \
322 .name = #idx,\
323 .binding = (_binding),\
324 .parent = (CLK_IS_ROOT),\
325 .clock_cfg = &(struct clk_stm32_fixed_rate_cfg){\
326 .rate = (_rate),\
327 },\
328 .ops = &clk_stm32_fixed_rate_ops,\
329 }
330
331#define BYPASS(_offset, _bit_byp, _bit_digbyp) &(struct stm32_clk_bypass){\
332 .offset = (_offset),\
333 .bit_byp = (_bit_byp),\
334 .bit_digbyp = (_bit_digbyp),\
335}
336
337#define CSS(_offset, _bit_css) &(struct stm32_clk_css){\
338 .offset = (_offset),\
339 .bit_css = (_bit_css),\
340}
341
342#define DRIVE(_offset, _shift, _width, _default) &(struct stm32_clk_drive){\
343 .offset = (_offset),\
344 .drv_shift = (_shift),\
345 .drv_width = (_width),\
346 .drv_default = (_default),\
347}
348
349#define OSCILLATOR(idx_osc, _id, _name, _gate_id, _gate_rdy_id, _bypass, _css, _drive) \
350 [(idx_osc)] = (struct clk_oscillator_data){\
351 .name = (_name),\
352 .id_clk = (_id),\
353 .gate_id = (_gate_id),\
354 .gate_rdy_id = (_gate_rdy_id),\
355 .bypass = (_bypass),\
356 .css = (_css),\
357 .drive = (_drive),\
358 }
359
360struct clk_oscillator_data *clk_oscillator_get_data(struct stm32_clk_priv *priv, int id);
361
362void clk_stm32_osc_init(struct stm32_clk_priv *priv, int id);
363bool clk_stm32_osc_gate_is_enabled(struct stm32_clk_priv *priv, int id);
364int clk_stm32_osc_gate_enable(struct stm32_clk_priv *priv, int id);
365void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id);
366
367struct stm32_osc_cfg {
368 int osc_id;
369};
370
371#define CLK_OSC(idx, _idx, _parent, _osc_id) \
372 [(idx)] = (struct clk_stm32){ \
373 .name = #idx,\
374 .binding = (_idx),\
375 .parent = (_parent),\
376 .flags = CLK_IS_CRITICAL,\
377 .clock_cfg = &(struct stm32_osc_cfg){\
378 .osc_id = (_osc_id),\
379 },\
380 .ops = &clk_stm32_osc_ops,\
381 }
382
383#define CLK_OSC_FIXED(idx, _idx, _parent, _osc_id) \
384 [(idx)] = (struct clk_stm32){ \
385 .name = #idx,\
386 .binding = (_idx),\
387 .parent = (_parent),\
388 .flags = CLK_IS_CRITICAL,\
389 .clock_cfg = &(struct stm32_osc_cfg){\
390 .osc_id = (_osc_id),\
391 },\
392 .ops = &clk_stm32_osc_nogate_ops,\
393 }
394
395extern const struct stm32_clk_ops clk_mux_ops;
396extern const struct stm32_clk_ops clk_stm32_divider_ops;
397extern const struct stm32_clk_ops clk_stm32_gate_ops;
398extern const struct stm32_clk_ops clk_fixed_factor_ops;
399extern const struct stm32_clk_ops clk_gate_ops;
400extern const struct stm32_clk_ops clk_timer_ops;
401extern const struct stm32_clk_ops clk_stm32_fixed_rate_ops;
402extern const struct stm32_clk_ops clk_stm32_osc_ops;
403extern const struct stm32_clk_ops clk_stm32_osc_nogate_ops;
404
405#endif /* CLK_STM32_CORE_H */