blob: baf2a996ef3bc7bf8b7f86f9dddaa63b52e4c5f6 [file] [log] [blame]
Gabriel Fernandez3db088a2022-11-24 11:36:04 +01001/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */
2/*
3 * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
4 * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
5 */
6
7struct stm32_clock_match_data;
8
9/**
10 * struct stm32_mux_cfg - multiplexer configuration
11 *
12 * @parent_names: array of string names for all possible parents
13 * @num_parents: number of possible parents
14 * @reg_off: register controlling multiplexer
15 * @shift: shift to multiplexer bit field
16 * @width: width of the multiplexer bit field
17 * @mux_flags: hardware-specific flags
18 * @table: array of register values corresponding to the parent
19 * index
20 */
21struct stm32_mux_cfg {
22 const char * const *parent_names;
23 u8 num_parents;
24 u32 reg_off;
25 u8 shift;
26 u8 width;
27 u8 mux_flags;
28 u32 *table;
29};
30
31/**
32 * struct stm32_gate_cfg - gating configuration
33 *
34 * @reg_off: register controlling gate
35 * @bit_idx: single bit controlling gate
36 * @gate_flags: hardware-specific flags
37 * @set_clr: 0 : normal gate, 1 : has a register to clear the gate
38 */
39struct stm32_gate_cfg {
40 u32 reg_off;
41 u8 bit_idx;
42 u8 gate_flags;
43 u8 set_clr;
44};
45
46/**
47 * struct stm32_div_cfg - divider configuration
48 *
49 * @reg_off: register containing the divider
50 * @shift: shift to the divider bit field
51 * @width: width of the divider bit field
52 * @table: array of value/divider pairs, last entry should have div = 0
53 */
54struct stm32_div_cfg {
55 u32 reg_off;
56 u8 shift;
57 u8 width;
58 u8 div_flags;
59 const struct clk_div_table *table;
60};
61
62#define NO_STM32_MUX -1
63#define NO_STM32_DIV -1
64#define NO_STM32_GATE -1
65
66/**
67 * struct stm32_composite_cfg - composite configuration
68 *
69 * @mux: index of a multiplexer
70 * @gate: index of a gate
71 * @div: index of a divider
72 */
73struct stm32_composite_cfg {
74 int mux;
75 int gate;
76 int div;
77};
78
79/**
80 * struct clock_config - clock configuration
81 *
82 * @id: binding id of the clock
83 * @name: clock name
84 * @parent_name: name of the clock parent
85 * @flags: framework-specific flags
86 * @sec_id: secure id (use to known if the clock is secured or not)
87 * @clock_cfg: specific clock data configuration
88 * @setup: specific call back to reister the clock (will use
89 * clock_cfg data as input)
90 */
91struct clock_config {
92 unsigned long id;
93 const char *name;
94 const char *parent_name;
95 unsigned long flags;
96 int sec_id;
97 void *clock_cfg;
98
99 struct clk *(*setup)(struct udevice *dev,
100 const struct clock_config *cfg);
101};
102
103/**
104 * struct clk_stm32_clock_data - clock data
105 *
106 * @num_gates: number of defined gates
107 * @gates: array of gate configuration
108 * @muxes: array of multiplexer configuration
109 * @dividers: array of divider configuration
110 */
111struct clk_stm32_clock_data {
112 unsigned int num_gates;
113 const struct stm32_gate_cfg *gates;
114 const struct stm32_mux_cfg *muxes;
115 const struct stm32_div_cfg *dividers;
116};
117
118/**
119 * struct stm32_clock_match_data - clock match data
120 *
121 * @num_gates: number of clocks
122 * @tab_clocks: array of clock configuration
123 * @clock_data: definition of all gates / dividers / multiplexers
124 * @check_security: call back to check if clock is secured or not
125 */
126struct stm32_clock_match_data {
127 unsigned int num_clocks;
128 const struct clock_config *tab_clocks;
129 const struct clk_stm32_clock_data *clock_data;
Gabriel Fernandez299487c2025-05-27 15:27:45 +0200130 int (*check_security)(struct udevice *dev, void __iomem *base,
Gabriel Fernandez3db088a2022-11-24 11:36:04 +0100131 const struct clock_config *cfg);
132};
133
134/**
135 * struct stm32mp_rcc_priv - private struct for stm32mp clocks
136 *
137 * @base: base register of RCC driver
138 * @gate_cpt: array of refcounting for gate with more than one
139 * clocks as input. See explanation of Peripheral clock enabling
140 * below.
141 * @data: data for gate / divider / multiplexer configuration
142 */
143struct stm32mp_rcc_priv {
144 void __iomem *base;
145 u8 *gate_cpt;
146 const struct clk_stm32_clock_data *data;
Marek Vasut0b44b9c2025-05-12 19:08:29 +0200147 struct clk osc_clk[6];
Gabriel Fernandez3db088a2022-11-24 11:36:04 +0100148};
149
150int stm32_rcc_init(struct udevice *dev,
151 const struct stm32_clock_match_data *data);
152
153/**
154 * STM32 Gate
155 *
156 * PCE (Peripheral Clock Enabling) Peripheral
157 *
158 * ------------------------------ ----------
159 * | | | |
160 * | | | PERx |
161 * bus_ck | ----- | | |
162 * ------------->|------------------| | | ckg_bus_perx | |
163 * | | AND |-----|---------------->| |
164 * | -----------| | | | |
165 * | | ----- | | |
166 * | | | | |
167 * | ----- | | |
168 * Perx_EN |-----|---| GCL | Gating | | |
169 * | ----- Control | | |
170 * | | Logic | | |
171 * | | | | |
172 * | | ----- | | |
173 * | -----------| | | ckg_ker_perx | |
174 * perx_ker_ck | | AND |-----|---------------->| |
175 * ------------->|------------------| | | | |
176 * | ----- | | |
177 * | | | |
178 * | | | |
179 * ------------------------------ ----------
180
181 * Each peripheral requires a bus interface clock, named ckg_bus_perx
Michal Simekcc046dc2024-04-16 08:55:19 +0200182 * (for peripheral `x').
Gabriel Fernandez3db088a2022-11-24 11:36:04 +0100183 * Some peripherals (SAI, UART...) need also a dedicated clock for their
184 * communication interface, this clock is generally asynchronous with respect to
185 * the bus interface clock, and is named kernel clock (ckg_ker_perx).
186
187 * Both clocks can be gated by one Perx_EN enable bit.
188 * Then we have to manage a refcounting on gate level to avoid gate if one
189 * the bus or the Kernel was enable.
190 *
191 * Example:
Michal Simekcc046dc2024-04-16 08:55:19 +0200192 * 1) enable the bus clock
193 * --> bus_clk ref_counting = 1, gate_ref_count = 1
194 * 2) enable the kernel clock
195 * --> perx_ker_ck ref_counting = 1, gate_ref_count = 2
196 * 3) disable kernel clock
197 * ---> perx_ker_ck ref_counting = 0, gate_ref_count = 1
198 * ==> then i will not gate because gate_ref_count > 0
199 * 4) disable bus clock
200 * --> bus_clk ref_counting = 0, gate_ref_count = 0
201 * ==> then i can gate (write in the register) because
Gabriel Fernandez3db088a2022-11-24 11:36:04 +0100202 * gate_ref_count = 0
203 */
204
205struct clk_stm32_gate {
206 struct clk clk;
207 struct stm32mp_rcc_priv *priv;
208 int gate_id;
209};
210
211#define to_clk_stm32_gate(_clk) container_of(_clk, struct clk_stm32_gate, clk)
212
213struct clk *
214clk_stm32_gate_register(struct udevice *dev,
215 const struct clock_config *cfg);
216
217struct clk *
218clk_stm32_register_composite(struct udevice *dev,
219 const struct clock_config *cfg);
220
221struct stm32_clk_gate_cfg {
222 int gate_id;
223};
224
225#define STM32_GATE(_id, _name, _parent, _flags, _gate_id, _sec_id) \
226{ \
227 .id = _id, \
228 .sec_id = _sec_id, \
229 .name = _name, \
230 .parent_name = _parent, \
231 .flags = _flags, \
232 .clock_cfg = &(struct stm32_clk_gate_cfg) { \
233 .gate_id = _gate_id, \
234 }, \
235 .setup = clk_stm32_gate_register, \
236}
237
238struct stm32_clk_composite_cfg {
239 int gate_id;
240 int mux_id;
241 int div_id;
242};
243
244#define STM32_COMPOSITE(_id, _name, _flags, _sec_id, \
245 _gate_id, _mux_id, _div_id) \
246{ \
247 .id = _id, \
248 .name = _name, \
249 .sec_id = _sec_id, \
250 .flags = _flags, \
251 .clock_cfg = &(struct stm32_clk_composite_cfg) { \
252 .gate_id = _gate_id, \
253 .mux_id = _mux_id, \
254 .div_id = _div_id, \
255 }, \
256 .setup = clk_stm32_register_composite, \
257}
258
259#define STM32_COMPOSITE_NOMUX(_id, _name, _parent, _flags, _sec_id, \
260 _gate_id, _div_id) \
261{ \
262 .id = _id, \
263 .name = _name, \
264 .parent_name = _parent, \
265 .sec_id = _sec_id, \
266 .flags = _flags, \
267 .clock_cfg = &(struct stm32_clk_composite_cfg) { \
268 .gate_id = _gate_id, \
269 .mux_id = NO_STM32_MUX, \
270 .div_id = _div_id, \
271 }, \
272 .setup = clk_stm32_register_composite, \
273}
274
275extern const struct clk_ops stm32_clk_ops;
276
277ulong clk_stm32_get_rate_by_name(const char *name);