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 const uint32_t nb_gates; 46 const struct div_cfg *div; 47 const uint32_t nb_div; 48 bool (*is_critical)(struct clk *clk); 49 void *pdata; 50 }; 51 52 struct clk_fixed_rate_cfg { 53 unsigned long rate; 54 }; 55 56 struct fixed_factor_cfg { 57 unsigned int mult; 58 unsigned int div; 59 }; 60 61 struct clk_gate_cfg { 62 uint32_t offset; 63 uint8_t bit_idx; 64 }; 65 66 struct clk_stm32_mux_cfg { 67 int mux_id; 68 }; 69 70 struct clk_stm32_gate_cfg { 71 int gate_id; 72 }; 73 74 struct clk_stm32_div_cfg { 75 int div_id; 76 }; 77 78 struct clk_stm32_composite_cfg { 79 int gate_id; 80 int div_id; 81 int mux_id; 82 }; 83 84 struct clk_stm32_timer_cfg { 85 uint32_t apbdiv; 86 uint32_t timpre; 87 }; 88 89 struct clk_stm32_gate_ready_cfg { 90 int gate_id; 91 int gate_rdy_id; 92 }; 93 94 /* Define for divider clocks */ 95 #define CLK_DIVIDER_ONE_BASED BIT(0) 96 #define CLK_DIVIDER_POWER_OF_TWO BIT(1) 97 #define CLK_DIVIDER_ALLOW_ZERO BIT(2) 98 #define CLK_DIVIDER_HIWORD_MASK BIT(3) 99 #define CLK_DIVIDER_ROUND_CLOSEST BIT(4) 100 #define CLK_DIVIDER_READ_ONLY BIT(5) 101 #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) 102 #define CLK_DIVIDER_BIG_ENDIAN BIT(7) 103 104 #define DIV_NO_RDY UINT8_MAX 105 #define MUX_NO_RDY UINT8_MAX 106 107 #define MASK_WIDTH_SHIFT(_width, _shift) \ 108 GENMASK_32(((_width) + (_shift) - 1U), (_shift)) 109 110 /* Define for composite clocks */ 111 #define NO_MUX INT32_MAX 112 #define NO_DIV INT32_MAX 113 #define NO_GATE INT32_MAX 114 115 void stm32_gate_enable(uint16_t gate_id); 116 void stm32_gate_disable(uint16_t gate_id); 117 bool stm32_gate_is_enabled(uint16_t gate_id); 118 TEE_Result stm32_gate_wait_ready(uint16_t gate_id, bool ready_on); 119 TEE_Result stm32_gate_rdy_enable(uint16_t gate_id); 120 TEE_Result stm32_gate_rdy_disable(uint16_t gate_id); 121 122 size_t stm32_mux_get_parent(uint32_t mux_id); 123 TEE_Result stm32_mux_set_parent(uint16_t pid, uint8_t sel); 124 125 TEE_Result stm32_div_set_rate(int div_id, unsigned long rate, 126 unsigned long prate); 127 128 uint32_t stm32_div_get_value(int div_id); 129 TEE_Result stm32_div_set_value(uint32_t div_id, uint32_t value); 130 131 int clk_stm32_parse_fdt_by_name(const void *fdt, int node, const char *name, 132 uint32_t *tab, uint32_t *nb); 133 134 unsigned long clk_stm32_divider_get_rate(struct clk *clk, 135 unsigned long parent_rate); 136 137 TEE_Result clk_stm32_divider_set_rate(struct clk *clk, 138 unsigned long rate, 139 unsigned long parent_rate); 140 141 size_t clk_stm32_composite_get_parent(struct clk *clk); 142 TEE_Result clk_stm32_composite_set_parent(struct clk *clk, size_t pidx); 143 unsigned long clk_stm32_composite_get_rate(struct clk *clk, 144 unsigned long parent_rate); 145 TEE_Result clk_stm32_composite_set_rate(struct clk *clk, unsigned long rate, 146 unsigned long parent_rate); 147 TEE_Result clk_stm32_composite_gate_enable(struct clk *clk); 148 void clk_stm32_composite_gate_disable(struct clk *clk); 149 150 TEE_Result clk_stm32_set_parent_by_index(struct clk *clk, size_t pidx); 151 152 extern const struct clk_ops clk_fixed_factor_ops; 153 extern const struct clk_ops clk_fixed_clk_ops; 154 extern const struct clk_ops clk_stm32_gate_ops; 155 extern const struct clk_ops clk_stm32_gate_ready_ops; 156 extern const struct clk_ops clk_stm32_divider_ops; 157 extern const struct clk_ops clk_stm32_mux_ops; 158 extern const struct clk_ops clk_stm32_composite_ops; 159 160 #define PARENT(x...) { x } 161 162 #define STM32_FIXED_RATE(_name, _rate)\ 163 struct clk _name = {\ 164 .ops = &clk_fixed_clk_ops,\ 165 .priv = &(struct clk_fixed_rate_cfg) {\ 166 .rate = (_rate),\ 167 },\ 168 .name = #_name,\ 169 .flags = 0,\ 170 .num_parents = 0,\ 171 } 172 173 #define STM32_FIXED_FACTOR(_name, _parent, _flags, _mult, _div)\ 174 struct clk _name = {\ 175 .ops = &clk_fixed_factor_ops,\ 176 .priv = &(struct fixed_factor_cfg) {\ 177 .mult = _mult,\ 178 .div = _div,\ 179 },\ 180 .name = #_name,\ 181 .flags = (_flags),\ 182 .num_parents = 1,\ 183 .parents = { (_parent) },\ 184 } 185 186 #define STM32_GATE(_name, _parent, _flags, _gate_id)\ 187 struct clk _name = {\ 188 .ops = &clk_stm32_gate_ops,\ 189 .priv = &(struct clk_stm32_gate_cfg) {\ 190 .gate_id = _gate_id,\ 191 },\ 192 .name = #_name,\ 193 .flags = (_flags),\ 194 .num_parents = 1,\ 195 .parents = { (_parent) },\ 196 } 197 198 #define STM32_DIVIDER(_name, _parent, _flags, _div_id)\ 199 struct clk _name = {\ 200 .ops = &clk_stm32_divider_ops,\ 201 .priv = &(struct clk_stm32_div_cfg) {\ 202 .div_id = (_div_id),\ 203 },\ 204 .name = #_name,\ 205 .flags = (_flags),\ 206 .num_parents = 1,\ 207 .parents = { (_parent) },\ 208 } 209 210 #define STM32_MUX(_name, _nb_parents, _parents, _flags, _mux_id)\ 211 struct clk _name = {\ 212 .ops = &clk_stm32_mux_ops,\ 213 .priv = &(struct clk_stm32_mux_cfg) {\ 214 .mux_id = (_mux_id),\ 215 },\ 216 .name = #_name,\ 217 .flags = (_flags),\ 218 .num_parents = (_nb_parents),\ 219 .parents = _parents,\ 220 } 221 222 #define STM32_GATE_READY(_name, _parent, _flags, _gate_id)\ 223 struct clk _name = {\ 224 .ops = &clk_stm32_gate_ready_ops,\ 225 .priv = &(struct clk_stm32_gate_cfg) {\ 226 .gate_id = _gate_id,\ 227 },\ 228 .name = #_name,\ 229 .flags = (_flags),\ 230 .num_parents = 1,\ 231 .parents = { _parent },\ 232 } 233 234 #define STM32_COMPOSITE(_name, _nb_parents, _parents, _flags,\ 235 _gate_id, _div_id, _mux_id)\ 236 struct clk _name = {\ 237 .ops = &clk_stm32_composite_ops,\ 238 .priv = &(struct clk_stm32_composite_cfg) {\ 239 .gate_id = (_gate_id),\ 240 .div_id = (_div_id),\ 241 .mux_id = (_mux_id),\ 242 },\ 243 .name = #_name,\ 244 .flags = (_flags),\ 245 .num_parents = (_nb_parents),\ 246 .parents = _parents,\ 247 } 248 249 struct clk_stm32_priv *clk_stm32_get_priv(void); 250 uintptr_t clk_stm32_get_rcc_base(void); 251 252 TEE_Result clk_stm32_init(struct clk_stm32_priv *priv, uintptr_t base); 253 254 void stm32mp_clk_provider_probe_final(const void *fdt, int node, 255 struct clk_stm32_priv *priv); 256 257 #endif /* CLK_STM32_CORE_H */ 258