xref: /optee_os/core/include/drivers/clk.h (revision 05771552b189f8e9b05fa9ff3383370555b02ffc)
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 
19 /**
20  * struct clk - Clock structure
21  *
22  * @name: Clock name
23  * @priv: Private data for the clock provider
24  * @ops: Clock operations
25  * @parent: Current parent
26  * @rate: Current clock rate (cached after init or rate change)
27  * @flags: Specific clock flags
28  * @enabled_count: Enable/disable reference counter
29  * @num_parents: Number of parents
30  * @parents: Array of possible parents of the clock
31  * @link: Link the clock list
32  */
33 struct clk {
34 	const char *name;
35 	void *priv;
36 	const struct clk_ops *ops;
37 	struct clk *parent;
38 	unsigned long rate;
39 	unsigned int flags;
40 	struct refcount enabled_count;
41 #ifdef CFG_DRIVERS_CLK_PRINT_TREE
42 	SLIST_ENTRY(clk) link;
43 #endif
44 	size_t num_parents;
45 	struct clk *parents[];
46 };
47 
48 /**
49  * struct clk_duty_cycle - Encoding the duty cycle ratio of a clock
50  *
51  * @num:	Numerator of the duty cycle ratio
52  * @den:	Denominator of the duty cycle ratio
53  */
54 struct clk_duty_cycle {
55 	unsigned int num;
56 	unsigned int den;
57 };
58 
59 /**
60  * struct clk_ops
61  *
62  * @enable: Enable the clock
63  * @disable: Disable the clock
64  * @set_parent: Set the clock parent based on index
65  * @get_parent: Get the current parent index of the clock
66  * @set_rate: Set the clock rate
67  * @get_rate: Get the clock rate
68  * @get_rates_array: Get the supported clock rates as array
69  * @get_duty_cycle: Get duty cytcle of the clock
70  */
71 struct clk_ops {
72 	TEE_Result (*enable)(struct clk *clk);
73 	void (*disable)(struct clk *clk);
74 	TEE_Result (*set_parent)(struct clk *clk, size_t index);
75 	size_t (*get_parent)(struct clk *clk);
76 	TEE_Result (*set_rate)(struct clk *clk, unsigned long rate,
77 			       unsigned long parent_rate);
78 	unsigned long (*get_rate)(struct clk *clk,
79 				  unsigned long parent_rate);
80 	TEE_Result (*get_rates_array)(struct clk *clk, size_t start_index,
81 				      unsigned long *rates, size_t *nb_elts);
82 	TEE_Result (*get_duty_cycle)(struct clk *clk,
83 				     struct clk_duty_cycle *duty_cycle);
84 };
85 
86 /**
87  * Return the clock name
88  *
89  * @clk: Clock for which the name is needed
90  * Return a const char * pointing to the clock name
91  */
92 static inline const char *clk_get_name(struct clk *clk)
93 {
94 	return clk->name;
95 }
96 
97 /**
98  * clk_alloc - Allocate a clock structure
99  *
100  * @name: Clock name
101  * @ops: Clock operations
102  * @parent_clks: Parents of the clock
103  * @parent_count: Number of parents of the clock
104  *
105  * Return a clock struct properly initialized or NULL if allocation failed
106  */
107 struct clk *clk_alloc(const char *name, const struct clk_ops *ops,
108 		      struct clk **parent_clks, size_t parent_count);
109 
110 /**
111  * clk_free - Free a clock structure
112  *
113  * @clk: Clock to be freed or NULL
114  */
115 void clk_free(struct clk *clk);
116 
117 /**
118  * clk_register - Register a clock within the clock framework
119  *
120  * @clk: Clock struct to be registered
121  * Return a TEE_Result compliant value
122  */
123 TEE_Result clk_register(struct clk *clk);
124 
125 /**
126  * clk_get_rate - Get clock rate
127  *
128  * @clk: Clock for which the rate is needed
129  * Return the clock rate in Hz
130  */
131 unsigned long clk_get_rate(struct clk *clk);
132 
133 /**
134  * clk_set_rate - Set a clock rate
135  *
136  * @clk: Clock to be set with the rate
137  * @rate: Rate to set in Hz
138  * Return a TEE_Result compliant value
139  */
140 TEE_Result clk_set_rate(struct clk *clk, unsigned long rate);
141 
142 /**
143  * clk_enable - Enable a clock and its ascendance
144  *
145  * @clk: Clock to be enabled
146  * Return a TEE_Result compliant value
147  */
148 TEE_Result clk_enable(struct clk *clk);
149 
150 /**
151  * clk_disable - Disable a clock
152  *
153  * @clk: Clock to be disabled
154  */
155 void clk_disable(struct clk *clk);
156 
157 /**
158  * clk_is_enabled - Informative state on the clock
159  *
160  * This function is useful during specific system sequences where core
161  * executes atomically (primary core boot, some low power sequences).
162  *
163  * @clk: Clock refernece
164  */
165 bool clk_is_enabled(struct clk *clk);
166 
167 /**
168  * clk_get_parent - Get the current clock parent
169  *
170  * @clk: Clock for which the parent is needed
171  * Return the clock parent or NULL if there is no parent
172  */
173 struct clk *clk_get_parent(struct clk *clk);
174 
175 /**
176  * clk_get_num_parents - Get the number of parents for a clock
177  *
178  * @clk: Clock for which the number of parents is needed
179  * Return the number of parents
180  */
181 static inline size_t clk_get_num_parents(struct clk *clk)
182 {
183 	return clk->num_parents;
184 }
185 
186 /**
187  * Get a clock parent by its index
188  *
189  * @clk: Clock for which the parent is needed
190  * @pidx: Parent index for the clock
191  * Return the clock parent at index @pidx or NULL if out of bound
192  */
193 struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx);
194 
195 /**
196  * clk_set_parent - Set the current clock parent
197  *
198  * @clk: Clock for which the parent should be set
199  * @parent: Parent clock to set
200  * Return a TEE_Result compliant value
201  */
202 TEE_Result clk_set_parent(struct clk *clk, struct clk *parent);
203 
204 /**
205  * clk_get_rates_array - Get supported rates as an array
206  *
207  * @clk: Clock for which the rates are requested
208  * @start_index: start index of requested rates
209  * @rates: Array of rates allocated by caller or NULL to query count of rates
210  * @nb_elts: Max number of elements that the array can hold as input. Contains
211  * the number of elements that was added in the array as output.
212  * Returns a TEE_Result compliant value
213  */
214 TEE_Result clk_get_rates_array(struct clk *clk, size_t start_index,
215 			       unsigned long *rates, size_t *nb_elts);
216 
217 /**
218  * clk_get_duty_cycle - Get clock duty cycle
219  *
220  * @clk: Clock for which the duty cycle is requested
221  * @duty: Output duty cycle info
222  * Return a TEE_Result compliant value
223  */
224 TEE_Result clk_get_duty_cycle(struct clk *clk,
225 			      struct clk_duty_cycle *duty_cycle);
226 
227 /* Print current clock tree summary to output console with debug trace level */
228 #ifdef CFG_DRIVERS_CLK
229 void clk_print_tree(void);
230 #else
231 static inline void clk_print_tree(void)
232 {
233 }
234 #endif /* CFG_DRIVERS_CLK */
235 #endif /* __DRIVERS_CLK_H */
236