1 /* 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 
7 struct 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  */
21 struct 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  */
39 struct 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  */
54 struct 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  */
73 struct 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  */
91 struct 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  */
111 struct 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  */
126 struct 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;
130 	int (*check_security)(void __iomem *base,
131 			      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  */
143 struct stm32mp_rcc_priv {
144 	void __iomem *base;
145 	u8 *gate_cpt;
146 	const struct clk_stm32_clock_data *data;
147 };
148 
149 int stm32_rcc_init(struct udevice *dev,
150 		   const struct stm32_clock_match_data *data);
151 
152 /**
153  * STM32 Gate
154  *
155  *               PCE (Peripheral Clock Enabling)                  Peripheral
156  *
157  *                ------------------------------                   ----------
158  *               |                              |                 |          |
159  *               |                              |                 |   PERx   |
160  * bus_ck        |                   -----      |                 |          |
161  * ------------->|------------------|     |     |  ckg_bus_perx   |          |
162  *               |                  | AND |-----|---------------->|          |
163  *               |       -----------|     |     |                 |          |
164  *               |      |            -----      |                 |          |
165  *               |      |                       |                 |          |
166  *               |    -----                     |                 |          |
167  * Perx_EN |-----|---| GCL |  Gating            |                 |          |
168  *               |    -----   Control           |                 |          |
169  *               |      |     Logic             |                 |          |
170  *               |      |                       |                 |          |
171  *               |      |            -----      |                 |          |
172  *               |       -----------|     |     |  ckg_ker_perx   |          |
173  * perx_ker_ck   |                  | AND |-----|---------------->|          |
174  * ------------->|------------------|     |     |                 |          |
175  *               |                   -----      |                 |          |
176  *               |                              |                 |          |
177  *               |                              |                 |          |
178  *                ------------------------------                   ----------
179 
180  * Each peripheral requires a bus interface clock, named ckg_bus_perx
181  * (for peripheral ‘x’).
182  * Some peripherals (SAI, UART...) need also a dedicated clock for their
183  * communication interface, this clock is generally asynchronous with respect to
184  * the bus interface clock, and is named kernel clock (ckg_ker_perx).
185 
186  * Both clocks can be gated by one Perx_EN enable bit.
187  * Then we have to manage a refcounting on gate level to avoid gate if one
188  * the bus or the Kernel was enable.
189  *
190  * Example:
191  * 1) enable the bus clock
192  *	--> bus_clk ref_counting = 1, gate_ref_count = 1
193  * 2) enable the kernel clock
194  *	--> perx_ker_ck ref_counting = 1, gate_ref_count = 2
195  * 3) disable kernel clock
196  * 	---> perx_ker_ck ref_counting = 0, gate_ref_count = 1
197  * 	==> then i will not gate because gate_ref_count > 0
198  * 4) disable bus clock
199  *	--> bus_clk  ref_counting  = 0, gate_ref_count = 0
200  *	==> then i can gate (write in the register) because
201  *	    gate_ref_count = 0
202  */
203 
204 struct clk_stm32_gate {
205 	struct clk clk;
206 	struct stm32mp_rcc_priv *priv;
207 	int gate_id;
208 };
209 
210 #define to_clk_stm32_gate(_clk) container_of(_clk, struct clk_stm32_gate, clk)
211 
212 struct clk *
213 clk_stm32_gate_register(struct udevice *dev,
214 			const struct clock_config *cfg);
215 
216 struct clk *
217 clk_stm32_register_composite(struct udevice *dev,
218 			     const struct clock_config *cfg);
219 
220 struct stm32_clk_gate_cfg {
221 	int gate_id;
222 };
223 
224 #define STM32_GATE(_id, _name, _parent, _flags, _gate_id, _sec_id) \
225 { \
226 	.id		= _id, \
227 	.sec_id		= _sec_id, \
228 	.name		= _name, \
229 	.parent_name	= _parent, \
230 	.flags		= _flags, \
231 	.clock_cfg	= &(struct stm32_clk_gate_cfg) { \
232 		.gate_id	= _gate_id, \
233 	}, \
234 	.setup		= clk_stm32_gate_register, \
235 }
236 
237 struct stm32_clk_composite_cfg {
238 	int	gate_id;
239 	int	mux_id;
240 	int	div_id;
241 };
242 
243 #define STM32_COMPOSITE(_id, _name, _flags, _sec_id, \
244 			_gate_id, _mux_id, _div_id) \
245 { \
246 	.id		= _id, \
247 	.name		= _name, \
248 	.sec_id		= _sec_id, \
249 	.flags		= _flags, \
250 	.clock_cfg	= &(struct stm32_clk_composite_cfg) { \
251 		.gate_id	= _gate_id, \
252 		.mux_id		= _mux_id, \
253 		.div_id		= _div_id, \
254 	}, \
255 	.setup		= clk_stm32_register_composite, \
256 }
257 
258 #define STM32_COMPOSITE_NOMUX(_id, _name, _parent, _flags, _sec_id, \
259 			      _gate_id, _div_id) \
260 { \
261 	.id		= _id, \
262 	.name		= _name, \
263 	.parent_name	= _parent, \
264 	.sec_id		= _sec_id, \
265 	.flags		= _flags, \
266 	.clock_cfg	= &(struct stm32_clk_composite_cfg) { \
267 		.gate_id	= _gate_id, \
268 		.mux_id		= NO_STM32_MUX, \
269 		.div_id		= _div_id, \
270 	}, \
271 	.setup		= clk_stm32_register_composite, \
272 }
273 
274 extern const struct clk_ops stm32_clk_ops;
275 
276 ulong clk_stm32_get_rate_by_name(const char *name);
277