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