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