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