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 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 */ 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 */ 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 as an array 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 debug trace level. 254 */ 255 void clk_print_tree(void); 256 #else 257 static inline void clk_print_tree(void) 258 { 259 } 260 #endif /* CFG_DRIVERS_CLK */ 261 #endif /* __DRIVERS_CLK_H */ 262