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