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 */ 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 */ 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