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 size_t stm32_mux_get_parent(uint32_t mux_id); 124 TEE_Result stm32_mux_set_parent(uint16_t pid, uint8_t sel); 125 126 TEE_Result stm32_div_set_rate(int div_id, unsigned long rate, 127 unsigned long prate); 128 129 uint32_t stm32_div_get_value(int div_id); 130 TEE_Result stm32_div_set_value(uint32_t div_id, uint32_t value); 131 132 int clk_stm32_parse_fdt_by_name(const void *fdt, int node, const char *name, 133 uint32_t *tab, uint32_t *nb); 134 135 unsigned long clk_stm32_divider_get_rate(struct clk *clk, 136 unsigned long parent_rate); 137 138 TEE_Result clk_stm32_divider_set_rate(struct clk *clk, 139 unsigned long rate, 140 unsigned long parent_rate); 141 142 size_t clk_stm32_composite_get_parent(struct clk *clk); 143 TEE_Result clk_stm32_composite_set_parent(struct clk *clk, size_t pidx); 144 unsigned long clk_stm32_composite_get_rate(struct clk *clk, 145 unsigned long parent_rate); 146 TEE_Result clk_stm32_composite_set_rate(struct clk *clk, unsigned long rate, 147 unsigned long parent_rate); 148 TEE_Result clk_stm32_composite_gate_enable(struct clk *clk); 149 void clk_stm32_composite_gate_disable(struct clk *clk); 150 151 TEE_Result clk_stm32_set_parent_by_index(struct clk *clk, size_t pidx); 152 153 extern const struct clk_ops clk_fixed_factor_ops; 154 extern const struct clk_ops clk_fixed_clk_ops; 155 extern const struct clk_ops clk_stm32_gate_ops; 156 extern const struct clk_ops clk_stm32_gate_ready_ops; 157 extern const struct clk_ops clk_stm32_divider_ops; 158 extern const struct clk_ops clk_stm32_mux_ops; 159 extern const struct clk_ops clk_stm32_composite_ops; 160 161 #define PARENT(x...) { x } 162 163 #define STM32_FIXED_RATE(_name, _rate)\ 164 struct clk _name = {\ 165 .ops = &clk_fixed_clk_ops,\ 166 .priv = &(struct clk_fixed_rate_cfg) {\ 167 .rate = (_rate),\ 168 },\ 169 .name = #_name,\ 170 .flags = 0,\ 171 .num_parents = 0,\ 172 } 173 174 #define STM32_FIXED_FACTOR(_name, _parent, _flags, _mult, _div)\ 175 struct clk _name = {\ 176 .ops = &clk_fixed_factor_ops,\ 177 .priv = &(struct fixed_factor_cfg) {\ 178 .mult = _mult,\ 179 .div = _div,\ 180 },\ 181 .name = #_name,\ 182 .flags = (_flags),\ 183 .num_parents = 1,\ 184 .parents = { (_parent) },\ 185 } 186 187 #define STM32_GATE(_name, _parent, _flags, _gate_id)\ 188 struct clk _name = {\ 189 .ops = &clk_stm32_gate_ops,\ 190 .priv = &(struct clk_stm32_gate_cfg) {\ 191 .gate_id = _gate_id,\ 192 },\ 193 .name = #_name,\ 194 .flags = (_flags),\ 195 .num_parents = 1,\ 196 .parents = { (_parent) },\ 197 } 198 199 #define STM32_DIVIDER(_name, _parent, _flags, _div_id)\ 200 struct clk _name = {\ 201 .ops = &clk_stm32_divider_ops,\ 202 .priv = &(struct clk_stm32_div_cfg) {\ 203 .div_id = (_div_id),\ 204 },\ 205 .name = #_name,\ 206 .flags = (_flags),\ 207 .num_parents = 1,\ 208 .parents = { (_parent) },\ 209 } 210 211 #define STM32_MUX(_name, _nb_parents, _parents, _flags, _mux_id)\ 212 struct clk _name = {\ 213 .ops = &clk_stm32_mux_ops,\ 214 .priv = &(struct clk_stm32_mux_cfg) {\ 215 .mux_id = (_mux_id),\ 216 },\ 217 .name = #_name,\ 218 .flags = (_flags),\ 219 .num_parents = (_nb_parents),\ 220 .parents = _parents,\ 221 } 222 223 #define STM32_GATE_READY(_name, _parent, _flags, _gate_id)\ 224 struct clk _name = {\ 225 .ops = &clk_stm32_gate_ready_ops,\ 226 .priv = &(struct clk_stm32_gate_cfg) {\ 227 .gate_id = _gate_id,\ 228 },\ 229 .name = #_name,\ 230 .flags = (_flags),\ 231 .num_parents = 1,\ 232 .parents = { _parent },\ 233 } 234 235 #define STM32_COMPOSITE(_name, _nb_parents, _parents, _flags,\ 236 _gate_id, _div_id, _mux_id)\ 237 struct clk _name = {\ 238 .ops = &clk_stm32_composite_ops,\ 239 .priv = &(struct clk_stm32_composite_cfg) {\ 240 .gate_id = (_gate_id),\ 241 .div_id = (_div_id),\ 242 .mux_id = (_mux_id),\ 243 },\ 244 .name = #_name,\ 245 .flags = (_flags),\ 246 .num_parents = (_nb_parents),\ 247 .parents = _parents,\ 248 } 249 250 struct clk_stm32_priv *clk_stm32_get_priv(void); 251 uintptr_t clk_stm32_get_rcc_base(void); 252 253 TEE_Result clk_stm32_init(struct clk_stm32_priv *priv, uintptr_t base); 254 255 void stm32mp_clk_provider_probe_final(const void *fdt, int node, 256 struct clk_stm32_priv *priv); 257 258 #endif /* CLK_STM32_CORE_H */ 259