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 <tee_api_types.h>
12 
13 /* Flags for clock */
14 #define CLK_SET_RATE_GATE	BIT(0) /* must be gated across rate change */
15 #define CLK_SET_PARENT_GATE	BIT(1) /* must be gated across re-parent */
16 
17 /**
18  * struct clk - Clock structure
19  *
20  * @name: Clock name
21  * @priv: Private data for the clock provider
22  * @ops: Clock operations
23  * @parent: Current parent
24  * @rate: Current clock rate (cached after init or rate change)
25  * @flags: Specific clock flags
26  * @enabled_count: Enable/disable reference counter
27  * @num_parents: Number of parents
28  * @parents: Array of possible parents of the clock
29  */
30 struct clk {
31 	const char *name;
32 	void *priv;
33 	const struct clk_ops *ops;
34 	struct clk *parent;
35 	unsigned long rate;
36 	unsigned int flags;
37 	struct refcount enabled_count;
38 	size_t num_parents;
39 	struct clk *parents[];
40 };
41 
42 /**
43  * struct clk_ops
44  *
45  * @enable: Enable the clock
46  * @disable: Disable the clock
47  * @set_parent: Set the clock parent based on index
48  * @get_parent: Get the current parent index of the clock
49  * @set_rate: Set the clock rate
50  * @get_rate: Get the clock rate
51  * @get_rates_array: Get the supported clock rates as array
52  */
53 struct clk_ops {
54 	TEE_Result (*enable)(struct clk *clk);
55 	void (*disable)(struct clk *clk);
56 	TEE_Result (*set_parent)(struct clk *clk, size_t index);
57 	size_t (*get_parent)(struct clk *clk);
58 	TEE_Result (*set_rate)(struct clk *clk, unsigned long rate,
59 			       unsigned long parent_rate);
60 	unsigned long (*get_rate)(struct clk *clk,
61 				  unsigned long parent_rate);
62 	TEE_Result (*get_rates_array)(struct clk *clk, size_t start_index,
63 				      unsigned long *rates, size_t *nb_elts);
64 };
65 
66 /**
67  * Return the clock name
68  *
69  * @clk: Clock for which the name is needed
70  * Return a const char * pointing to the clock name
71  */
clk_get_name(struct clk * clk)72 static inline const char *clk_get_name(struct clk *clk)
73 {
74 	return clk->name;
75 }
76 
77 /**
78  * clk_alloc - Allocate a clock structure
79  *
80  * @name: Clock name
81  * @ops: Clock operations
82  * @parent_clks: Parents of the clock
83  * @parent_count: Number of parents of the clock
84  *
85  * Return a clock struct properly initialized or NULL if allocation failed
86  */
87 struct clk *clk_alloc(const char *name, const struct clk_ops *ops,
88 		      struct clk **parent_clks, size_t parent_count);
89 
90 /**
91  * clk_free - Free a clock structure
92  *
93  * @clk: Clock to be freed or NULL
94  */
95 void clk_free(struct clk *clk);
96 
97 /**
98  * clk_register - Register a clock within the clock framework
99  *
100  * @clk: Clock struct to be registered
101  * Return a TEE_Result compliant value
102  */
103 TEE_Result clk_register(struct clk *clk);
104 
105 /**
106  * clk_get_rate - Get clock rate
107  *
108  * @clk: Clock for which the rate is needed
109  * Return the clock rate in Hz
110  */
111 unsigned long clk_get_rate(struct clk *clk);
112 
113 /**
114  * clk_set_rate - Set a clock rate
115  *
116  * @clk: Clock to be set with the rate
117  * @rate: Rate to set in Hz
118  * Return a TEE_Result compliant value
119  */
120 TEE_Result clk_set_rate(struct clk *clk, unsigned long rate);
121 
122 /**
123  * clk_enable - Enable a clock and its ascendance
124  *
125  * @clk: Clock to be enabled
126  * Return a TEE_Result compliant value
127  */
128 TEE_Result clk_enable(struct clk *clk);
129 
130 /**
131  * clk_disable - Disable a clock
132  *
133  * @clk: Clock to be disabled
134  */
135 void clk_disable(struct clk *clk);
136 
137 /**
138  * clk_is_enabled - Informative state on the clock
139  *
140  * This function is useful during specific system sequences where core
141  * executes atomically (primary core boot, some low power sequences).
142  *
143  * @clk: Clock refernece
144  */
145 bool clk_is_enabled(struct clk *clk);
146 
147 /**
148  * clk_get_parent - Get the current clock parent
149  *
150  * @clk: Clock for which the parent is needed
151  * Return the clock parent or NULL if there is no parent
152  */
153 struct clk *clk_get_parent(struct clk *clk);
154 
155 /**
156  * clk_get_num_parents - Get the number of parents for a clock
157  *
158  * @clk: Clock for which the number of parents is needed
159  * Return the number of parents
160  */
clk_get_num_parents(struct clk * clk)161 static inline size_t clk_get_num_parents(struct clk *clk)
162 {
163 	return clk->num_parents;
164 }
165 
166 /**
167  * Get a clock parent by its index
168  *
169  * @clk: Clock for which the parent is needed
170  * @pidx: Parent index for the clock
171  * Return the clock parent at index @pidx or NULL if out of bound
172  */
173 struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx);
174 
175 /**
176  * clk_set_parent - Set the current clock parent
177  *
178  * @clk: Clock for which the parent should be set
179  * @parent: Parent clock to set
180  * Return a TEE_Result compliant value
181  */
182 TEE_Result clk_set_parent(struct clk *clk, struct clk *parent);
183 
184 /**
185  * clk_get_rates_array - Get supported rates as an array
186  *
187  * @clk: Clock for which the rates are requested
188  * @start_index: start index of requested rates
189  * @rates: Array of rates allocated by caller or NULL to query count of rates
190  * @nb_elts: Max number of elements that the array can hold as input. Contains
191  * the number of elements that was added in the array as output.
192  * Returns a TEE_Result compliant value
193  */
194 TEE_Result clk_get_rates_array(struct clk *clk, size_t start_index,
195 			       unsigned long *rates, size_t *nb_elts);
196 
197 #endif /* __DRIVERS_CLK_H */
198