xref: /optee_os/core/drivers/clk/clk-stm32-core.h (revision 2b028a2ba197af1fea5d1c6121a9482174285164)
1 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2 /*
3  * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
4  */
5 
6 #ifndef CLK_STM32_CORE_H
7 #define CLK_STM32_CORE_H
8 
9 #include <drivers/clk.h>
10 
11 struct mux_cfg {
12 	uint16_t offset;
13 	uint8_t shift;
14 	uint8_t width;
15 	uint8_t ready;
16 };
17 
18 struct gate_cfg {
19 	uint16_t offset;
20 	uint8_t bit_idx;
21 	uint8_t set_clr;
22 };
23 
24 struct div_table_cfg {
25 	unsigned int val;
26 	unsigned int div;
27 };
28 
29 struct div_cfg {
30 	uint16_t offset;
31 	uint8_t shift;
32 	uint8_t width;
33 	uint8_t flags;
34 	uint8_t ready;
35 	const struct div_table_cfg *table;
36 };
37 
38 struct clk_stm32_priv {
39 	uintptr_t base;
40 	size_t nb_clk_refs;
41 	struct clk **clk_refs;
42 	const struct mux_cfg *muxes;
43 	const uint32_t nb_muxes;
44 	const struct gate_cfg *gates;
45 	uint8_t *gate_cpt;
46 	const uint32_t nb_gates;
47 	const struct div_cfg *div;
48 	const uint32_t nb_div;
49 	bool (*is_critical)(struct clk *clk);
50 	void *pdata;
51 };
52 
53 struct clk_fixed_rate_cfg {
54 	unsigned long rate;
55 };
56 
57 struct fixed_factor_cfg {
58 	unsigned int mult;
59 	unsigned int div;
60 };
61 
62 struct clk_gate_cfg {
63 	uint32_t offset;
64 	uint8_t bit_idx;
65 };
66 
67 struct clk_stm32_mux_cfg {
68 	int mux_id;
69 };
70 
71 struct clk_stm32_gate_cfg {
72 	int gate_id;
73 };
74 
75 struct clk_stm32_div_cfg {
76 	int div_id;
77 };
78 
79 struct clk_stm32_composite_cfg {
80 	int gate_id;
81 	int div_id;
82 	int mux_id;
83 };
84 
85 struct clk_stm32_timer_cfg {
86 	uint32_t apbdiv;
87 	uint32_t timpre;
88 };
89 
90 struct clk_stm32_gate_ready_cfg {
91 	int gate_id;
92 	int gate_rdy_id;
93 };
94 
95 /* Define for divider clocks */
96 #define CLK_DIVIDER_ONE_BASED		BIT(0)
97 #define CLK_DIVIDER_POWER_OF_TWO	BIT(1)
98 #define CLK_DIVIDER_ALLOW_ZERO		BIT(2)
99 #define CLK_DIVIDER_HIWORD_MASK		BIT(3)
100 #define CLK_DIVIDER_ROUND_CLOSEST	BIT(4)
101 #define CLK_DIVIDER_READ_ONLY		BIT(5)
102 #define CLK_DIVIDER_MAX_AT_ZERO		BIT(6)
103 #define CLK_DIVIDER_BIG_ENDIAN		BIT(7)
104 
105 #define DIV_NO_RDY		UINT8_MAX
106 #define MUX_NO_RDY		UINT8_MAX
107 
108 #define MASK_WIDTH_SHIFT(_width, _shift) \
109 	GENMASK_32(((_width) + (_shift) - 1U), (_shift))
110 
111 /* Define for composite clocks */
112 #define NO_MUX		INT32_MAX
113 #define NO_DIV		INT32_MAX
114 #define NO_GATE		INT32_MAX
115 
116 void stm32_gate_enable(uint16_t gate_id);
117 void stm32_gate_disable(uint16_t gate_id);
118 bool stm32_gate_is_enabled(uint16_t gate_id);
119 TEE_Result stm32_gate_wait_ready(uint16_t gate_id, bool ready_on);
120 TEE_Result stm32_gate_rdy_enable(uint16_t gate_id);
121 TEE_Result stm32_gate_rdy_disable(uint16_t gate_id);
122 
123 size_t stm32_mux_get_parent(uint32_t mux_id);
124 TEE_Result stm32_mux_set_parent(uint16_t pid, uint8_t sel);
125 
126 TEE_Result stm32_div_set_rate(int div_id, unsigned long rate,
127 			      unsigned long prate);
128 
129 uint32_t stm32_div_get_value(int div_id);
130 TEE_Result stm32_div_set_value(uint32_t div_id, uint32_t value);
131 
132 int clk_stm32_parse_fdt_by_name(const void *fdt, int node, const char *name,
133 				uint32_t *tab, uint32_t *nb);
134 
135 unsigned long clk_stm32_divider_get_rate(struct clk *clk,
136 					 unsigned long parent_rate);
137 
138 TEE_Result clk_stm32_divider_set_rate(struct clk *clk,
139 				      unsigned long rate,
140 				      unsigned long parent_rate);
141 
142 size_t clk_stm32_composite_get_parent(struct clk *clk);
143 TEE_Result clk_stm32_composite_set_parent(struct clk *clk, size_t pidx);
144 unsigned long clk_stm32_composite_get_rate(struct clk *clk,
145 					   unsigned long parent_rate);
146 TEE_Result clk_stm32_composite_set_rate(struct clk *clk, unsigned long rate,
147 					unsigned long parent_rate);
148 TEE_Result clk_stm32_composite_gate_enable(struct clk *clk);
149 void clk_stm32_composite_gate_disable(struct clk *clk);
150 
151 TEE_Result clk_stm32_set_parent_by_index(struct clk *clk, size_t pidx);
152 
153 extern const struct clk_ops clk_fixed_factor_ops;
154 extern const struct clk_ops clk_fixed_clk_ops;
155 extern const struct clk_ops clk_stm32_gate_ops;
156 extern const struct clk_ops clk_stm32_gate_ready_ops;
157 extern const struct clk_ops clk_stm32_divider_ops;
158 extern const struct clk_ops clk_stm32_mux_ops;
159 extern const struct clk_ops clk_stm32_composite_ops;
160 
161 #define PARENT(x...) { x }
162 
163 #define STM32_FIXED_RATE(_name, _rate)\
164 	struct clk _name = {\
165 		.ops = &clk_fixed_clk_ops,\
166 		.priv = &(struct clk_fixed_rate_cfg) {\
167 			.rate = (_rate),\
168 		},\
169 		.name = #_name,\
170 		.flags = 0,\
171 		.num_parents = 0,\
172 	}
173 
174 #define STM32_FIXED_FACTOR(_name, _parent, _flags, _mult, _div)\
175 	struct clk _name = {\
176 		.ops = &clk_fixed_factor_ops,\
177 		.priv = &(struct fixed_factor_cfg) {\
178 			.mult = _mult,\
179 			.div = _div,\
180 		},\
181 		.name = #_name,\
182 		.flags = (_flags),\
183 		.num_parents = 1,\
184 		.parents = { (_parent) },\
185 	}
186 
187 #define STM32_GATE(_name, _parent, _flags, _gate_id)\
188 	struct clk _name = {\
189 		.ops = &clk_stm32_gate_ops,\
190 		.priv = &(struct clk_stm32_gate_cfg) {\
191 			.gate_id = _gate_id,\
192 		},\
193 		.name = #_name,\
194 		.flags = (_flags),\
195 		.num_parents = 1,\
196 		.parents = { (_parent) },\
197 	}
198 
199 #define STM32_DIVIDER(_name, _parent, _flags, _div_id)\
200 	struct clk _name = {\
201 		.ops = &clk_stm32_divider_ops,\
202 		.priv = &(struct clk_stm32_div_cfg) {\
203 			.div_id = (_div_id),\
204 		},\
205 		.name = #_name,\
206 		.flags = (_flags),\
207 		.num_parents = 1,\
208 		.parents = { (_parent) },\
209 	}
210 
211 #define STM32_MUX(_name, _nb_parents, _parents, _flags, _mux_id)\
212 	struct clk _name = {\
213 		.ops = &clk_stm32_mux_ops,\
214 		.priv = &(struct clk_stm32_mux_cfg) {\
215 			.mux_id = (_mux_id),\
216 		},\
217 		.name = #_name,\
218 		.flags = (_flags),\
219 		.num_parents = (_nb_parents),\
220 		.parents = _parents,\
221 	}
222 
223 #define STM32_GATE_READY(_name, _parent, _flags, _gate_id)\
224 	struct clk _name = {\
225 		.ops = &clk_stm32_gate_ready_ops,\
226 		.priv = &(struct clk_stm32_gate_cfg) {\
227 			.gate_id = _gate_id,\
228 		},\
229 		.name = #_name,\
230 		.flags = (_flags),\
231 		.num_parents = 1,\
232 		.parents = { _parent },\
233 	}
234 
235 #define STM32_COMPOSITE(_name, _nb_parents, _parents, _flags,\
236 			_gate_id, _div_id, _mux_id)\
237 	struct clk _name = {\
238 		.ops = &clk_stm32_composite_ops,\
239 		.priv = &(struct clk_stm32_composite_cfg) {\
240 			.gate_id = (_gate_id),\
241 			.div_id = (_div_id),\
242 			.mux_id = (_mux_id),\
243 		},\
244 		.name = #_name,\
245 		.flags = (_flags),\
246 		.num_parents = (_nb_parents),\
247 		.parents = _parents,\
248 	}
249 
250 struct clk_stm32_priv *clk_stm32_get_priv(void);
251 uintptr_t clk_stm32_get_rcc_base(void);
252 
253 TEE_Result clk_stm32_init(struct clk_stm32_priv *priv, uintptr_t base);
254 
255 void stm32mp_clk_provider_probe_final(const void *fdt, int node,
256 				      struct clk_stm32_priv *priv);
257 
258 #endif /* CLK_STM32_CORE_H */
259