1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (c) 2021, Bootlin
4 */
5
6 #ifndef __DRIVERS_CLK_H
7 #define __DRIVERS_CLK_H
8
9 #include <kernel/refcount.h>
10 #include <stdint.h>
11 #include <sys/queue.h>
12 #include <tee_api_types.h>
13
14 /* Flags for clock */
15 #define CLK_SET_RATE_GATE BIT(0) /* must be gated across rate change */
16 #define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */
17 #define CLK_DUTY_CYCLE_PARENT BIT(2) /* forward duty cycle call to parent */
18 #define CLK_SET_RATE_PARENT BIT(3) /* propagate rate change up to parent */
19 #define CLK_SET_RATE_UNGATE BIT(4) /* clock needs to run to set rate */
20 #define CLK_SET_PARENT_PRE_ENABLE BIT(5) /* enable new parent if needed */
21
22 /**
23 * struct clk - Clock structure
24 *
25 * @name: Clock name
26 * @priv: Private data for the clock provider
27 * @ops: Clock operations
28 * @parent: Current parent
29 * @rate: Current clock rate (cached after init or rate change)
30 * @flags: Specific clock flags
31 * @enabled_count: Enable/disable reference counter
32 * @num_parents: Number of parents
33 * @parents: Array of possible parents of the clock
34 * @link: Link the clock list
35 */
36 struct clk {
37 const char *name;
38 void *priv;
39 const struct clk_ops *ops;
40 struct clk *parent;
41 unsigned long rate;
42 unsigned int flags;
43 struct refcount enabled_count;
44 #ifdef CFG_DRIVERS_CLK_PRINT_TREE
45 SLIST_ENTRY(clk) link;
46 #endif
47 size_t num_parents;
48 struct clk *parents[];
49 };
50
51 /**
52 * struct clk_duty_cycle - Encoding the duty cycle ratio of a clock
53 *
54 * @num: Numerator of the duty cycle ratio
55 * @den: Denominator of the duty cycle ratio
56 */
57 struct clk_duty_cycle {
58 unsigned int num;
59 unsigned int den;
60 };
61
62 /**
63 * struct clk_ops - Clock operations
64 *
65 * @enable: Enable the clock
66 * @disable: Disable the clock
67 * @set_parent: Set the clock parent based on index
68 * @get_parent: Get the current parent index of the clock
69 * @set_rate: Set the clock rate
70 * @get_rate: Get the clock rate
71 * @get_rates_array: Get the supported clock rates as array in ascending order
72 * @get_rates_steps: Get support clock rates by min/max/step representation
73 * @get_duty_cycle: Get duty cytcle of the clock
74 *
75 * All clock operations are expected to execute in a interruptible thread
76 * context at the exclusion of power management sequence where non secure
77 * world is not operating (power off, suspend, resume).
78 */
79 struct clk_ops {
80 TEE_Result (*enable)(struct clk *clk);
81 void (*disable)(struct clk *clk);
82 TEE_Result (*set_parent)(struct clk *clk, size_t index);
83 size_t (*get_parent)(struct clk *clk);
84 TEE_Result (*set_rate)(struct clk *clk, unsigned long rate,
85 unsigned long parent_rate);
86 unsigned long (*get_rate)(struct clk *clk,
87 unsigned long parent_rate);
88 TEE_Result (*get_rates_array)(struct clk *clk, size_t start_index,
89 unsigned long *rates, size_t *nb_elts);
90 TEE_Result (*get_rates_steps)(struct clk *clk, unsigned long *min,
91 unsigned long *max, unsigned long *step);
92 TEE_Result (*get_duty_cycle)(struct clk *clk,
93 struct clk_duty_cycle *duty_cycle);
94 };
95
96 /**
97 * clk_get_name() - Return the clock name
98 *
99 * @clk: Clock for which the name is needed
100 * Return a const char * pointing to the clock name
101 */
clk_get_name(struct clk * clk)102 static inline const char *clk_get_name(struct clk *clk)
103 {
104 return clk->name;
105 }
106
107 /**
108 * clk_alloc() - Allocate a clock structure
109 *
110 * @name: Clock name
111 * @ops: Clock operations
112 * @parent_clks: Parents of the clock
113 * @parent_count: Number of parents of the clock
114 *
115 * Return a clock struct properly initialized or NULL if allocation failed
116 */
117 struct clk *clk_alloc(const char *name, const struct clk_ops *ops,
118 struct clk **parent_clks, size_t parent_count);
119
120 /**
121 * clk_free() - Free a clock structure
122 *
123 * @clk: Clock to be freed or NULL
124 */
125 void clk_free(struct clk *clk);
126
127 /**
128 * clk_register() - Register a clock within the clock framework
129 *
130 * @clk: Clock struct to be registered
131 * Return a TEE_Result compliant value
132 */
133 TEE_Result clk_register(struct clk *clk);
134
135 /**
136 * clk_get_rate() - Get clock rate
137 *
138 * @clk: Clock for which the rate is needed
139 * Return the clock rate in Hz
140 */
141 unsigned long clk_get_rate(struct clk *clk);
142
143 /**
144 * clk_set_rate() - Set a clock rate
145 *
146 * @clk: Clock to be set with the rate
147 * @rate: Rate to set in Hz
148 * Return a TEE_Result compliant value
149 */
150 TEE_Result clk_set_rate(struct clk *clk, unsigned long rate);
151
152 /**
153 * clk_enable() - Enable a clock and its ascendance
154 *
155 * @clk: Clock to be enabled
156 * Return a TEE_Result compliant value
157 */
158 TEE_Result clk_enable(struct clk *clk);
159
160 /**
161 * clk_disable() - Disable a clock
162 *
163 * @clk: Clock to be disabled
164 */
165 void clk_disable(struct clk *clk);
166
167 /**
168 * clk_is_enabled() - Informative state on the clock
169 *
170 * This function is useful during specific system sequences where core
171 * executes atomically (primary core boot, some low power sequences).
172 *
173 * @clk: Clock refernece
174 */
175 bool clk_is_enabled(struct clk *clk);
176
177 /**
178 * clk_get_parent() - Get the current clock parent
179 *
180 * @clk: Clock for which the parent is needed
181 * Return the clock parent or NULL if there is no parent
182 */
183 struct clk *clk_get_parent(struct clk *clk);
184
185 /**
186 * clk_get_num_parents() - Get the number of parents for a clock
187 *
188 * @clk: Clock for which the number of parents is needed
189 * Return the number of parents
190 */
clk_get_num_parents(struct clk * clk)191 static inline size_t clk_get_num_parents(struct clk *clk)
192 {
193 return clk->num_parents;
194 }
195
196 /**
197 * clk_get_parent_by_index() - Get a clock parent by its index
198 *
199 * @clk: Clock for which the parent is needed
200 * @pidx: Parent index for the clock
201 * Return the clock parent at index @pidx or NULL if out of bound
202 */
203 struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx);
204
205 /**
206 * clk_set_parent() - Set the current clock parent
207 *
208 * @clk: Clock for which the parent should be set
209 * @parent: Parent clock to set
210 * Return a TEE_Result compliant value
211 */
212 TEE_Result clk_set_parent(struct clk *clk, struct clk *parent);
213
214 /**
215 * clk_get_rates_array() - Get supported rates in ascending order
216 *
217 * @clk: Clock for which the rates are requested
218 * @start_index: start index of requested rates
219 * @rates: Array of rates allocated by caller or NULL to query count of rates
220 * @nb_elts: Max number of elements that the array can hold as input. Contains
221 * the number of elements that was added in the array as output.
222 * Returns a TEE_Result compliant value
223 */
224 TEE_Result clk_get_rates_array(struct clk *clk, size_t start_index,
225 unsigned long *rates, size_t *nb_elts);
226
227 /**
228 * clk_get_rates_steps() - Get supported rates as min/max/step triplet
229 *
230 * @clk: Clock for which the rates are requested
231 * @min: Output min supported rate in Hz
232 * @max: Output max supported rate in Hz
233 * @step: Output rate step in Hz
234 * Returns a TEE_Result compliant value
235 */
236 TEE_Result clk_get_rates_steps(struct clk *clk, unsigned long *min,
237 unsigned long *max, unsigned long *step);
238
239 /**
240 * clk_get_duty_cycle() - Get clock duty cycle
241 *
242 * @clk: Clock for which the duty cycle is requested
243 * @duty: Output duty cycle info
244 * Return a TEE_Result compliant value
245 */
246 TEE_Result clk_get_duty_cycle(struct clk *clk,
247 struct clk_duty_cycle *duty_cycle);
248
249 #ifdef CFG_DRIVERS_CLK
250 /**
251 * clk_print_tree() - Print current clock tree summary to output console
252 *
253 * The clock is printed with the info trace level.
254 */
255 void clk_print_tree(void);
256 #else
clk_print_tree(void)257 static inline void clk_print_tree(void)
258 {
259 }
260 #endif /* CFG_DRIVERS_CLK */
261 #endif /* __DRIVERS_CLK_H */
262