1 /* 2 * Copyright (C) 2022, STMicroelectronics - All Rights Reserved 3 * 4 * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 5 */ 6 7 #ifndef CLK_STM32_CORE_H 8 #define CLK_STM32_CORE_H 9 10 struct mux_cfg { 11 uint16_t offset; 12 uint8_t shift; 13 uint8_t width; 14 uint8_t bitrdy; 15 }; 16 17 struct gate_cfg { 18 uint16_t offset; 19 uint8_t bit_idx; 20 uint8_t set_clr; 21 }; 22 23 struct clk_div_table { 24 unsigned int val; 25 unsigned int div; 26 }; 27 28 struct div_cfg { 29 uint16_t offset; 30 uint8_t shift; 31 uint8_t width; 32 uint8_t flags; 33 uint8_t bitrdy; 34 const struct clk_div_table *table; 35 }; 36 37 struct parent_cfg { 38 uint8_t num_parents; 39 const uint16_t *id_parents; 40 struct mux_cfg *mux; 41 }; 42 43 struct stm32_clk_priv; 44 45 struct stm32_clk_ops { 46 unsigned long (*recalc_rate)(struct stm32_clk_priv *priv, int id, unsigned long rate); 47 int (*get_parent)(struct stm32_clk_priv *priv, int id); 48 int (*set_rate)(struct stm32_clk_priv *priv, int id, unsigned long rate, 49 unsigned long prate); 50 int (*enable)(struct stm32_clk_priv *priv, int id); 51 void (*disable)(struct stm32_clk_priv *priv, int id); 52 bool (*is_enabled)(struct stm32_clk_priv *priv, int id); 53 void (*init)(struct stm32_clk_priv *priv, int id); 54 }; 55 56 struct clk_stm32 { 57 const char *name; 58 uint16_t binding; 59 uint16_t parent; 60 uint8_t flags; 61 void *clock_cfg; 62 const struct stm32_clk_ops *ops; 63 }; 64 65 struct stm32_clk_priv { 66 uintptr_t base; 67 const uint32_t num; 68 const struct clk_stm32 *clks; 69 const struct parent_cfg *parents; 70 const uint32_t nb_parents; 71 const struct gate_cfg *gates; 72 const uint32_t nb_gates; 73 const struct div_cfg *div; 74 const uint32_t nb_div; 75 struct clk_oscillator_data *osci_data; 76 const uint32_t nb_osci_data; 77 uint32_t *gate_refcounts; 78 void *pdata; 79 }; 80 81 struct stm32_clk_bypass { 82 uint16_t offset; 83 uint8_t bit_byp; 84 uint8_t bit_digbyp; 85 }; 86 87 struct stm32_clk_css { 88 uint16_t offset; 89 uint8_t bit_css; 90 }; 91 92 struct stm32_clk_drive { 93 uint16_t offset; 94 uint8_t drv_shift; 95 uint8_t drv_width; 96 uint8_t drv_default; 97 }; 98 99 struct clk_oscillator_data { 100 const char *name; 101 uint16_t id_clk; 102 unsigned long frequency; 103 uint16_t gate_id; 104 uint16_t gate_rdy_id; 105 struct stm32_clk_bypass *bypass; 106 struct stm32_clk_css *css; 107 struct stm32_clk_drive *drive; 108 }; 109 110 struct clk_fixed_rate { 111 const char *name; 112 unsigned long fixed_rate; 113 }; 114 115 struct clk_gate_cfg { 116 uint32_t offset; 117 uint8_t bit_idx; 118 }; 119 120 /* CLOCK FLAGS */ 121 #define CLK_IS_CRITICAL BIT(0) 122 #define CLK_IGNORE_UNUSED BIT(1) 123 #define CLK_SET_RATE_PARENT BIT(2) 124 125 #define CLK_DIVIDER_ONE_BASED BIT(0) 126 #define CLK_DIVIDER_POWER_OF_TWO BIT(1) 127 #define CLK_DIVIDER_ALLOW_ZERO BIT(2) 128 #define CLK_DIVIDER_HIWORD_MASK BIT(3) 129 #define CLK_DIVIDER_ROUND_CLOSEST BIT(4) 130 #define CLK_DIVIDER_READ_ONLY BIT(5) 131 #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) 132 #define CLK_DIVIDER_BIG_ENDIAN BIT(7) 133 134 #define MUX_MAX_PARENTS U(0x8000) 135 #define MUX_PARENT_MASK GENMASK(14, 0) 136 #define MUX_FLAG U(0x8000) 137 #define MUX(mux) ((mux) | MUX_FLAG) 138 139 #define NO_GATE 0 140 #define _NO_ID UINT16_MAX 141 #define CLK_IS_ROOT UINT16_MAX 142 #define MUX_NO_BIT_RDY UINT8_MAX 143 #define DIV_NO_BIT_RDY UINT8_MAX 144 145 #define MASK_WIDTH_SHIFT(_width, _shift) \ 146 GENMASK(((_width) + (_shift) - 1U), (_shift)) 147 148 int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base); 149 void clk_stm32_enable_critical_clocks(void); 150 151 struct stm32_clk_priv *clk_stm32_get_priv(void); 152 153 int clk_get_index(struct stm32_clk_priv *priv, unsigned long binding_id); 154 const struct clk_stm32 *_clk_get(struct stm32_clk_priv *priv, int id); 155 156 void clk_oscillator_set_bypass(struct stm32_clk_priv *priv, int id, bool digbyp, bool bypass); 157 void clk_oscillator_set_drive(struct stm32_clk_priv *priv, int id, uint8_t lsedrv); 158 void clk_oscillator_set_css(struct stm32_clk_priv *priv, int id, bool css); 159 160 int _clk_stm32_gate_wait_ready(struct stm32_clk_priv *priv, uint16_t gate_id, bool ready_on); 161 162 int clk_oscillator_wait_ready(struct stm32_clk_priv *priv, int id, bool ready_on); 163 int clk_oscillator_wait_ready_on(struct stm32_clk_priv *priv, int id); 164 int clk_oscillator_wait_ready_off(struct stm32_clk_priv *priv, int id); 165 166 const char *_clk_stm32_get_name(struct stm32_clk_priv *priv, int id); 167 const char *clk_stm32_get_name(struct stm32_clk_priv *priv, unsigned long binding_id); 168 int clk_stm32_get_counter(unsigned long binding_id); 169 170 void _clk_stm32_gate_disable(struct stm32_clk_priv *priv, uint16_t gate_id); 171 int _clk_stm32_gate_enable(struct stm32_clk_priv *priv, uint16_t gate_id); 172 173 int _clk_stm32_set_parent(struct stm32_clk_priv *priv, int id, int src_id); 174 int _clk_stm32_set_parent_by_index(struct stm32_clk_priv *priv, int clk, int sel); 175 176 int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int id); 177 int _clk_stm32_get_parent_by_index(struct stm32_clk_priv *priv, int clk_id, int idx); 178 int _clk_stm32_get_parent_index(struct stm32_clk_priv *priv, int clk_id); 179 180 unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id); 181 unsigned long _clk_stm32_get_parent_rate(struct stm32_clk_priv *priv, int id); 182 183 bool _stm32_clk_is_flags(struct stm32_clk_priv *priv, int id, uint8_t flag); 184 185 int _clk_stm32_enable(struct stm32_clk_priv *priv, int id); 186 void _clk_stm32_disable(struct stm32_clk_priv *priv, int id); 187 188 int clk_stm32_enable_call_ops(struct stm32_clk_priv *priv, uint16_t id); 189 void clk_stm32_disable_call_ops(struct stm32_clk_priv *priv, uint16_t id); 190 191 bool _clk_stm32_is_enabled(struct stm32_clk_priv *priv, int id); 192 193 int _clk_stm32_divider_set_rate(struct stm32_clk_priv *priv, int div_id, 194 unsigned long rate, unsigned long parent_rate); 195 196 int clk_stm32_divider_set_rate(struct stm32_clk_priv *priv, int id, unsigned long rate, 197 unsigned long prate); 198 199 unsigned long _clk_stm32_divider_recalc(struct stm32_clk_priv *priv, 200 int div_id, 201 unsigned long prate); 202 203 unsigned long clk_stm32_divider_recalc(struct stm32_clk_priv *priv, int idx, 204 unsigned long prate); 205 206 int clk_stm32_gate_enable(struct stm32_clk_priv *priv, int idx); 207 void clk_stm32_gate_disable(struct stm32_clk_priv *priv, int idx); 208 209 bool _clk_stm32_gate_is_enabled(struct stm32_clk_priv *priv, int gate_id); 210 bool clk_stm32_gate_is_enabled(struct stm32_clk_priv *priv, int idx); 211 212 uint32_t clk_stm32_div_get_value(struct stm32_clk_priv *priv, int div_id); 213 int clk_stm32_set_div(struct stm32_clk_priv *priv, uint32_t div_id, uint32_t value); 214 int clk_mux_set_parent(struct stm32_clk_priv *priv, uint16_t pid, uint8_t sel); 215 int clk_mux_get_parent(struct stm32_clk_priv *priv, uint32_t mux_id); 216 217 int stm32_clk_parse_fdt_by_name(void *fdt, int node, const char *name, uint32_t *tab, uint32_t *nb); 218 219 #ifdef CFG_STM32_CLK_DEBUG 220 void clk_stm32_display_clock_info(void); 221 #endif 222 223 struct clk_stm32_div_cfg { 224 int id; 225 }; 226 227 #define STM32_DIV(idx, _binding, _parent, _flags, _div_id) \ 228 [(idx)] = (struct clk_stm32){ \ 229 .name = #idx,\ 230 .binding = (_binding),\ 231 .parent = (_parent),\ 232 .flags = (_flags),\ 233 .clock_cfg = &(struct clk_stm32_div_cfg){\ 234 .id = (_div_id),\ 235 },\ 236 .ops = &clk_stm32_divider_ops,\ 237 } 238 239 struct clk_stm32_gate_cfg { 240 int id; 241 }; 242 243 #define STM32_GATE(idx, _binding, _parent, _flags, _gate_id) \ 244 [(idx)] = (struct clk_stm32){ \ 245 .name = #idx,\ 246 .binding = (_binding),\ 247 .parent = (_parent),\ 248 .flags = (_flags),\ 249 .clock_cfg = &(struct clk_stm32_gate_cfg){\ 250 .id = (_gate_id),\ 251 },\ 252 .ops = &clk_stm32_gate_ops,\ 253 } 254 255 struct fixed_factor_cfg { 256 unsigned int mult; 257 unsigned int div; 258 }; 259 260 unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv, 261 int _idx, unsigned long prate); 262 263 #define FIXED_FACTOR(idx, _idx, _parent, _mult, _div) \ 264 [(idx)] = (struct clk_stm32){ \ 265 .name = #idx,\ 266 .binding = (_idx),\ 267 .parent = (_parent),\ 268 .clock_cfg = &(struct fixed_factor_cfg){\ 269 .mult = (_mult),\ 270 .div = (_div),\ 271 },\ 272 .ops = &clk_fixed_factor_ops,\ 273 } 274 275 #define GATE(idx, _binding, _parent, _flags, _offset, _bit_idx) \ 276 [(idx)] = (struct clk_stm32){ \ 277 .name = #idx,\ 278 .binding = (_binding),\ 279 .parent = (_parent),\ 280 .flags = (_flags),\ 281 .clock_cfg = &(struct clk_gate_cfg){\ 282 .offset = (_offset),\ 283 .bit_idx = (_bit_idx),\ 284 },\ 285 .ops = &clk_gate_ops,\ 286 } 287 288 #define STM32_MUX(idx, _binding, _mux_id, _flags) \ 289 [(idx)] = (struct clk_stm32){ \ 290 .name = #idx,\ 291 .binding = (_binding),\ 292 .parent = (MUX(_mux_id)),\ 293 .flags = (_flags),\ 294 .clock_cfg = NULL,\ 295 .ops = (&clk_mux_ops),\ 296 } 297 298 struct clk_timer_cfg { 299 uint32_t apbdiv; 300 uint32_t timpre; 301 }; 302 303 #define CK_TIMER(idx, _idx, _parent, _flags, _apbdiv, _timpre) \ 304 [(idx)] = (struct clk_stm32){ \ 305 .name = #idx,\ 306 .binding = (_idx),\ 307 .parent = (_parent),\ 308 .flags = (CLK_SET_RATE_PARENT | (_flags)),\ 309 .clock_cfg = &(struct clk_timer_cfg){\ 310 .apbdiv = (_apbdiv),\ 311 .timpre = (_timpre),\ 312 },\ 313 .ops = &clk_timer_ops,\ 314 } 315 316 struct clk_stm32_fixed_rate_cfg { 317 unsigned long rate; 318 }; 319 320 #define CLK_FIXED_RATE(idx, _binding, _rate) \ 321 [(idx)] = (struct clk_stm32){ \ 322 .name = #idx,\ 323 .binding = (_binding),\ 324 .parent = (CLK_IS_ROOT),\ 325 .clock_cfg = &(struct clk_stm32_fixed_rate_cfg){\ 326 .rate = (_rate),\ 327 },\ 328 .ops = &clk_stm32_fixed_rate_ops,\ 329 } 330 331 #define BYPASS(_offset, _bit_byp, _bit_digbyp) &(struct stm32_clk_bypass){\ 332 .offset = (_offset),\ 333 .bit_byp = (_bit_byp),\ 334 .bit_digbyp = (_bit_digbyp),\ 335 } 336 337 #define CSS(_offset, _bit_css) &(struct stm32_clk_css){\ 338 .offset = (_offset),\ 339 .bit_css = (_bit_css),\ 340 } 341 342 #define DRIVE(_offset, _shift, _width, _default) &(struct stm32_clk_drive){\ 343 .offset = (_offset),\ 344 .drv_shift = (_shift),\ 345 .drv_width = (_width),\ 346 .drv_default = (_default),\ 347 } 348 349 #define OSCILLATOR(idx_osc, _id, _name, _gate_id, _gate_rdy_id, _bypass, _css, _drive) \ 350 [(idx_osc)] = (struct clk_oscillator_data){\ 351 .name = (_name),\ 352 .id_clk = (_id),\ 353 .gate_id = (_gate_id),\ 354 .gate_rdy_id = (_gate_rdy_id),\ 355 .bypass = (_bypass),\ 356 .css = (_css),\ 357 .drive = (_drive),\ 358 } 359 360 struct clk_oscillator_data *clk_oscillator_get_data(struct stm32_clk_priv *priv, int id); 361 362 void clk_stm32_osc_init(struct stm32_clk_priv *priv, int id); 363 bool clk_stm32_osc_gate_is_enabled(struct stm32_clk_priv *priv, int id); 364 int clk_stm32_osc_gate_enable(struct stm32_clk_priv *priv, int id); 365 void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id); 366 367 struct stm32_osc_cfg { 368 int osc_id; 369 }; 370 371 #define CLK_OSC(idx, _idx, _parent, _osc_id) \ 372 [(idx)] = (struct clk_stm32){ \ 373 .name = #idx,\ 374 .binding = (_idx),\ 375 .parent = (_parent),\ 376 .flags = CLK_IS_CRITICAL,\ 377 .clock_cfg = &(struct stm32_osc_cfg){\ 378 .osc_id = (_osc_id),\ 379 },\ 380 .ops = &clk_stm32_osc_ops,\ 381 } 382 383 #define CLK_OSC_FIXED(idx, _idx, _parent, _osc_id) \ 384 [(idx)] = (struct clk_stm32){ \ 385 .name = #idx,\ 386 .binding = (_idx),\ 387 .parent = (_parent),\ 388 .flags = CLK_IS_CRITICAL,\ 389 .clock_cfg = &(struct stm32_osc_cfg){\ 390 .osc_id = (_osc_id),\ 391 },\ 392 .ops = &clk_stm32_osc_nogate_ops,\ 393 } 394 395 extern const struct stm32_clk_ops clk_mux_ops; 396 extern const struct stm32_clk_ops clk_stm32_divider_ops; 397 extern const struct stm32_clk_ops clk_stm32_gate_ops; 398 extern const struct stm32_clk_ops clk_fixed_factor_ops; 399 extern const struct stm32_clk_ops clk_gate_ops; 400 extern const struct stm32_clk_ops clk_timer_ops; 401 extern const struct stm32_clk_ops clk_stm32_fixed_rate_ops; 402 extern const struct stm32_clk_ops clk_stm32_osc_ops; 403 extern const struct stm32_clk_ops clk_stm32_osc_nogate_ops; 404 405 #endif /* CLK_STM32_CORE_H */ 406