1 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 /* 3 * Copyright (C) STMicroelectronics 2022 - All Rights Reserved 4 */ 5 6 #ifndef CLK_STM32_CORE_H 7 #define CLK_STM32_CORE_H 8 9 #include <drivers/clk.h> 10 11 struct mux_cfg { 12 uint16_t offset; 13 uint8_t shift; 14 uint8_t width; 15 uint8_t ready; 16 }; 17 18 struct gate_cfg { 19 uint16_t offset; 20 uint8_t bit_idx; 21 uint8_t set_clr; 22 }; 23 24 struct div_table_cfg { 25 unsigned int val; 26 unsigned int div; 27 }; 28 29 struct div_cfg { 30 uint16_t offset; 31 uint8_t shift; 32 uint8_t width; 33 uint8_t flags; 34 uint8_t ready; 35 const struct div_table_cfg *table; 36 }; 37 38 struct clk_stm32_priv { 39 uintptr_t base; 40 size_t nb_clk_refs; 41 struct clk **clk_refs; 42 const struct mux_cfg *muxes; 43 const uint32_t nb_muxes; 44 const struct gate_cfg *gates; 45 uint8_t *gate_cpt; 46 const uint32_t nb_gates; 47 const struct div_cfg *div; 48 const uint32_t nb_div; 49 bool (*is_critical)(struct clk *clk); 50 void *pdata; 51 }; 52 53 struct clk_fixed_rate_cfg { 54 unsigned long rate; 55 }; 56 57 struct fixed_factor_cfg { 58 unsigned int mult; 59 unsigned int div; 60 }; 61 62 struct clk_gate_cfg { 63 uint32_t offset; 64 uint8_t bit_idx; 65 }; 66 67 struct clk_stm32_mux_cfg { 68 int mux_id; 69 }; 70 71 struct clk_stm32_gate_cfg { 72 int gate_id; 73 }; 74 75 struct clk_stm32_div_cfg { 76 int div_id; 77 }; 78 79 struct clk_stm32_composite_cfg { 80 int gate_id; 81 int div_id; 82 int mux_id; 83 }; 84 85 struct clk_stm32_timer_cfg { 86 uint32_t apbdiv; 87 uint32_t timpre; 88 }; 89 90 struct clk_stm32_gate_ready_cfg { 91 int gate_id; 92 int gate_rdy_id; 93 }; 94 95 /* Define for divider clocks */ 96 #define CLK_DIVIDER_ONE_BASED BIT(0) 97 #define CLK_DIVIDER_POWER_OF_TWO BIT(1) 98 #define CLK_DIVIDER_ALLOW_ZERO BIT(2) 99 #define CLK_DIVIDER_HIWORD_MASK BIT(3) 100 #define CLK_DIVIDER_ROUND_CLOSEST BIT(4) 101 #define CLK_DIVIDER_READ_ONLY BIT(5) 102 #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) 103 #define CLK_DIVIDER_BIG_ENDIAN BIT(7) 104 105 #define DIV_NO_RDY UINT8_MAX 106 #define MUX_NO_RDY UINT8_MAX 107 108 #define MASK_WIDTH_SHIFT(_width, _shift) \ 109 GENMASK_32(((_width) + (_shift) - 1U), (_shift)) 110 111 /* Define for composite clocks */ 112 #define NO_MUX INT32_MAX 113 #define NO_DIV INT32_MAX 114 #define NO_GATE INT32_MAX 115 116 void stm32_gate_enable(uint16_t gate_id); 117 void stm32_gate_disable(uint16_t gate_id); 118 bool stm32_gate_is_enabled(uint16_t gate_id); 119 TEE_Result stm32_gate_wait_ready(uint16_t gate_id, bool ready_on); 120 TEE_Result stm32_gate_rdy_enable(uint16_t gate_id); 121 TEE_Result stm32_gate_rdy_disable(uint16_t gate_id); 122 123 /* 124 * Set gate to an enable or disable state without updating its 125 * refcount. This is exclusively intended to be used during initialization 126 * where refcount value are 0. 127 */ 128 void stm32_gate_set_init_state(uint16_t gate_id, bool enable); 129 130 size_t stm32_mux_get_parent(uint32_t mux_id); 131 TEE_Result stm32_mux_set_parent(uint16_t pid, uint8_t sel); 132 133 TEE_Result stm32_div_set_rate(int div_id, unsigned long rate, 134 unsigned long prate); 135 136 uint32_t stm32_div_get_value(int div_id); 137 TEE_Result stm32_div_set_value(uint32_t div_id, uint32_t value); 138 139 int clk_stm32_parse_fdt_by_name(const void *fdt, int node, const char *name, 140 uint32_t *tab, uint32_t *nb); 141 142 unsigned long clk_stm32_divider_get_rate(struct clk *clk, 143 unsigned long parent_rate); 144 145 TEE_Result clk_stm32_divider_set_rate(struct clk *clk, 146 unsigned long rate, 147 unsigned long parent_rate); 148 149 size_t clk_stm32_composite_get_parent(struct clk *clk); 150 TEE_Result clk_stm32_composite_set_parent(struct clk *clk, size_t pidx); 151 unsigned long clk_stm32_composite_get_rate(struct clk *clk, 152 unsigned long parent_rate); 153 TEE_Result clk_stm32_composite_set_rate(struct clk *clk, unsigned long rate, 154 unsigned long parent_rate); 155 TEE_Result clk_stm32_composite_gate_enable(struct clk *clk); 156 void clk_stm32_composite_gate_disable(struct clk *clk); 157 158 TEE_Result clk_stm32_set_parent_by_index(struct clk *clk, size_t pidx); 159 160 extern const struct clk_ops clk_fixed_factor_ops; 161 extern const struct clk_ops clk_fixed_clk_ops; 162 extern const struct clk_ops clk_stm32_gate_ops; 163 extern const struct clk_ops clk_stm32_gate_ready_ops; 164 extern const struct clk_ops clk_stm32_divider_ops; 165 extern const struct clk_ops clk_stm32_mux_ops; 166 extern const struct clk_ops clk_stm32_composite_ops; 167 168 #define PARENT(x...) { x } 169 170 #define STM32_FIXED_RATE(_name, _rate)\ 171 struct clk _name = {\ 172 .ops = &clk_fixed_clk_ops,\ 173 .priv = &(struct clk_fixed_rate_cfg) {\ 174 .rate = (_rate),\ 175 },\ 176 .name = #_name,\ 177 .flags = 0,\ 178 .num_parents = 0,\ 179 } 180 181 #define STM32_FIXED_FACTOR(_name, _parent, _flags, _mult, _div)\ 182 struct clk _name = {\ 183 .ops = &clk_fixed_factor_ops,\ 184 .priv = &(struct fixed_factor_cfg) {\ 185 .mult = _mult,\ 186 .div = _div,\ 187 },\ 188 .name = #_name,\ 189 .flags = (_flags),\ 190 .num_parents = 1,\ 191 .parents = { (_parent) },\ 192 } 193 194 #define STM32_GATE(_name, _parent, _flags, _gate_id)\ 195 struct clk _name = {\ 196 .ops = &clk_stm32_gate_ops,\ 197 .priv = &(struct clk_stm32_gate_cfg) {\ 198 .gate_id = _gate_id,\ 199 },\ 200 .name = #_name,\ 201 .flags = (_flags),\ 202 .num_parents = 1,\ 203 .parents = { (_parent) },\ 204 } 205 206 #define STM32_DIVIDER(_name, _parent, _flags, _div_id)\ 207 struct clk _name = {\ 208 .ops = &clk_stm32_divider_ops,\ 209 .priv = &(struct clk_stm32_div_cfg) {\ 210 .div_id = (_div_id),\ 211 },\ 212 .name = #_name,\ 213 .flags = (_flags),\ 214 .num_parents = 1,\ 215 .parents = { (_parent) },\ 216 } 217 218 #define STM32_MUX(_name, _nb_parents, _parents, _flags, _mux_id)\ 219 struct clk _name = {\ 220 .ops = &clk_stm32_mux_ops,\ 221 .priv = &(struct clk_stm32_mux_cfg) {\ 222 .mux_id = (_mux_id),\ 223 },\ 224 .name = #_name,\ 225 .flags = (_flags),\ 226 .num_parents = (_nb_parents),\ 227 .parents = _parents,\ 228 } 229 230 #define STM32_GATE_READY(_name, _parent, _flags, _gate_id)\ 231 struct clk _name = {\ 232 .ops = &clk_stm32_gate_ready_ops,\ 233 .priv = &(struct clk_stm32_gate_cfg) {\ 234 .gate_id = _gate_id,\ 235 },\ 236 .name = #_name,\ 237 .flags = (_flags),\ 238 .num_parents = 1,\ 239 .parents = { _parent },\ 240 } 241 242 #define STM32_COMPOSITE(_name, _nb_parents, _parents, _flags,\ 243 _gate_id, _div_id, _mux_id)\ 244 struct clk _name = {\ 245 .ops = &clk_stm32_composite_ops,\ 246 .priv = &(struct clk_stm32_composite_cfg) {\ 247 .gate_id = (_gate_id),\ 248 .div_id = (_div_id),\ 249 .mux_id = (_mux_id),\ 250 },\ 251 .name = #_name,\ 252 .flags = (_flags),\ 253 .num_parents = (_nb_parents),\ 254 .parents = _parents,\ 255 } 256 257 struct clk_stm32_priv *clk_stm32_get_priv(void); 258 uintptr_t clk_stm32_get_rcc_base(void); 259 260 TEE_Result clk_stm32_init(struct clk_stm32_priv *priv, uintptr_t base); 261 262 void stm32mp_clk_provider_probe_final(const void *fdt, int node, 263 struct clk_stm32_priv *priv); 264 265 #endif /* CLK_STM32_CORE_H */ 266