1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __MACH_IMX_CLK_H 3 #define __MACH_IMX_CLK_H 4 5 #include <linux/spinlock.h> 6 #include <linux/clk-provider.h> 7 8 extern spinlock_t imx_ccm_lock; 9 10 void imx_check_clocks(struct clk *clks[], unsigned int count); 11 void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count); 12 void imx_register_uart_clocks(struct clk ** const clks[]); 13 void imx_register_uart_clocks_hws(struct clk_hw ** const hws[]); 14 void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn); 15 void imx_unregister_clocks(struct clk *clks[], unsigned int count); 16 17 extern void imx_cscmr1_fixup(u32 *val); 18 19 enum imx_pllv1_type { 20 IMX_PLLV1_IMX1, 21 IMX_PLLV1_IMX21, 22 IMX_PLLV1_IMX25, 23 IMX_PLLV1_IMX27, 24 IMX_PLLV1_IMX31, 25 IMX_PLLV1_IMX35, 26 }; 27 28 enum imx_sccg_pll_type { 29 SCCG_PLL1, 30 SCCG_PLL2, 31 }; 32 33 enum imx_pll14xx_type { 34 PLL_1416X, 35 PLL_1443X, 36 }; 37 38 /* NOTE: Rate table should be kept sorted in descending order. */ 39 struct imx_pll14xx_rate_table { 40 unsigned int rate; 41 unsigned int pdiv; 42 unsigned int mdiv; 43 unsigned int sdiv; 44 unsigned int kdiv; 45 }; 46 47 struct imx_pll14xx_clk { 48 enum imx_pll14xx_type type; 49 const struct imx_pll14xx_rate_table *rate_table; 50 int rate_count; 51 int flags; 52 }; 53 54 #define imx_clk_busy_divider(name, parent_name, reg, shift, width, busy_reg, busy_shift) \ 55 imx_clk_hw_busy_divider(name, parent_name, reg, shift, width, busy_reg, busy_shift)->clk 56 57 #define imx_clk_busy_mux(name, reg, shift, width, busy_reg, busy_shift, parent_names, num_parents) \ 58 imx_clk_hw_busy_mux(name, reg, shift, width, busy_reg, busy_shift, parent_names, num_parents)->clk 59 60 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ 61 imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk 62 63 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ 64 cgr_val, clk_gate_flags, lock, share_count) \ 65 clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ 66 cgr_val, clk_gate_flags, lock, share_count)->clk 67 68 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \ 69 imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk 70 71 #define imx_clk_pfd(name, parent_name, reg, idx) \ 72 imx_clk_hw_pfd(name, parent_name, reg, idx)->clk 73 74 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \ 75 imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk 76 77 #define imx_clk_fixup_divider(name, parent, reg, shift, width, fixup) \ 78 imx_clk_hw_fixup_divider(name, parent, reg, shift, width, fixup)->clk 79 80 #define imx_clk_fixup_mux(name, reg, shift, width, parents, num_parents, fixup) \ 81 imx_clk_hw_fixup_mux(name, reg, shift, width, parents, num_parents, fixup)->clk 82 83 #define imx_clk_mux_ldb(name, reg, shift, width, parents, num_parents) \ 84 imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents)->clk 85 86 #define imx_clk_fixed_factor(name, parent, mult, div) \ 87 imx_clk_hw_fixed_factor(name, parent, mult, div)->clk 88 89 #define imx_clk_divider2(name, parent, reg, shift, width) \ 90 imx_clk_hw_divider2(name, parent, reg, shift, width)->clk 91 92 #define imx_clk_gate_dis(name, parent, reg, shift) \ 93 imx_clk_hw_gate_dis(name, parent, reg, shift)->clk 94 95 #define imx_clk_gate_dis_flags(name, parent, reg, shift, flags) \ 96 imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags)->clk 97 98 #define imx_clk_gate_flags(name, parent, reg, shift, flags) \ 99 imx_clk_hw_gate_flags(name, parent, reg, shift, flags)->clk 100 101 #define imx_clk_gate2(name, parent, reg, shift) \ 102 imx_clk_hw_gate2(name, parent, reg, shift)->clk 103 104 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \ 105 imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk 106 107 #define imx_clk_gate2_shared(name, parent, reg, shift, share_count) \ 108 imx_clk_hw_gate2_shared(name, parent, reg, shift, share_count)->clk 109 110 #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \ 111 imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk 112 113 #define imx_clk_gate3(name, parent, reg, shift) \ 114 imx_clk_hw_gate3(name, parent, reg, shift)->clk 115 116 #define imx_clk_gate4(name, parent, reg, shift) \ 117 imx_clk_hw_gate4(name, parent, reg, shift)->clk 118 119 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \ 120 imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk 121 122 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, 123 void __iomem *base, const struct imx_pll14xx_clk *pll_clk); 124 125 struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, 126 const char *parent, void __iomem *base); 127 128 struct clk *imx_clk_pllv2(const char *name, const char *parent, 129 void __iomem *base); 130 131 struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, 132 void __iomem *base); 133 134 struct clk *imx_clk_sccg_pll(const char *name, 135 const char * const *parent_names, 136 u8 num_parents, 137 u8 parent, u8 bypass1, u8 bypass2, 138 void __iomem *base, 139 unsigned long flags); 140 141 enum imx_pllv3_type { 142 IMX_PLLV3_GENERIC, 143 IMX_PLLV3_SYS, 144 IMX_PLLV3_USB, 145 IMX_PLLV3_USB_VF610, 146 IMX_PLLV3_AV, 147 IMX_PLLV3_ENET, 148 IMX_PLLV3_ENET_IMX7, 149 IMX_PLLV3_SYS_VF610, 150 IMX_PLLV3_DDR_IMX7, 151 IMX_PLLV3_AV_IMX7, 152 }; 153 154 struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, 155 const char *parent_name, void __iomem *base, u32 div_mask); 156 157 #define PLL_1416X_RATE(_rate, _m, _p, _s) \ 158 { \ 159 .rate = (_rate), \ 160 .mdiv = (_m), \ 161 .pdiv = (_p), \ 162 .sdiv = (_s), \ 163 } 164 165 #define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \ 166 { \ 167 .rate = (_rate), \ 168 .mdiv = (_m), \ 169 .pdiv = (_p), \ 170 .sdiv = (_s), \ 171 .kdiv = (_k), \ 172 } 173 174 struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name, 175 void __iomem *base); 176 177 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, 178 const char *parent_name, unsigned long flags, 179 void __iomem *reg, u8 bit_idx, u8 cgr_val, 180 u8 clk_gate_flags, spinlock_t *lock, 181 unsigned int *share_count); 182 183 struct clk * imx_obtain_fixed_clock( 184 const char *name, unsigned long rate); 185 186 struct clk_hw *imx_obtain_fixed_clock_hw( 187 const char *name, unsigned long rate); 188 189 struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np, 190 const char *name); 191 192 struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, 193 void __iomem *reg, u8 shift, u32 exclusive_mask); 194 195 struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, 196 void __iomem *reg, u8 idx); 197 198 struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name, 199 void __iomem *reg, u8 idx); 200 201 struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name, 202 void __iomem *reg, u8 shift, u8 width, 203 void __iomem *busy_reg, u8 busy_shift); 204 205 struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift, 206 u8 width, void __iomem *busy_reg, u8 busy_shift, 207 const char * const *parent_names, int num_parents); 208 209 struct clk_hw *imx7ulp_clk_composite(const char *name, 210 const char * const *parent_names, 211 int num_parents, bool mux_present, 212 bool rate_present, bool gate_present, 213 void __iomem *reg); 214 215 struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, 216 void __iomem *reg, u8 shift, u8 width, 217 void (*fixup)(u32 *val)); 218 219 struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg, 220 u8 shift, u8 width, const char * const *parents, 221 int num_parents, void (*fixup)(u32 *val)); 222 223 static inline struct clk *imx_clk_fixed(const char *name, int rate) 224 { 225 return clk_register_fixed_rate(NULL, name, NULL, 0, rate); 226 } 227 228 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate) 229 { 230 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); 231 } 232 233 static inline struct clk_hw *imx_clk_hw_mux_ldb(const char *name, void __iomem *reg, 234 u8 shift, u8 width, const char * const *parents, 235 int num_parents) 236 { 237 return clk_hw_register_mux(NULL, name, parents, num_parents, 238 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg, 239 shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock); 240 } 241 242 static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name, 243 const char *parent, unsigned int mult, unsigned int div) 244 { 245 return clk_hw_register_fixed_factor(NULL, name, parent, 246 CLK_SET_RATE_PARENT, mult, div); 247 } 248 249 static inline struct clk *imx_clk_divider(const char *name, const char *parent, 250 void __iomem *reg, u8 shift, u8 width) 251 { 252 return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, 253 reg, shift, width, 0, &imx_ccm_lock); 254 } 255 256 static inline struct clk_hw *imx_clk_hw_divider(const char *name, 257 const char *parent, 258 void __iomem *reg, u8 shift, 259 u8 width) 260 { 261 return clk_hw_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, 262 reg, shift, width, 0, &imx_ccm_lock); 263 } 264 265 static inline struct clk *imx_clk_divider_flags(const char *name, 266 const char *parent, void __iomem *reg, u8 shift, u8 width, 267 unsigned long flags) 268 { 269 return clk_register_divider(NULL, name, parent, flags, 270 reg, shift, width, 0, &imx_ccm_lock); 271 } 272 273 static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name, 274 const char *parent, 275 void __iomem *reg, u8 shift, 276 u8 width, unsigned long flags) 277 { 278 return clk_hw_register_divider(NULL, name, parent, flags, 279 reg, shift, width, 0, &imx_ccm_lock); 280 } 281 282 static inline struct clk_hw *imx_clk_hw_divider2(const char *name, const char *parent, 283 void __iomem *reg, u8 shift, u8 width) 284 { 285 return clk_hw_register_divider(NULL, name, parent, 286 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 287 reg, shift, width, 0, &imx_ccm_lock); 288 } 289 290 static inline struct clk *imx_clk_divider2_flags(const char *name, 291 const char *parent, void __iomem *reg, u8 shift, u8 width, 292 unsigned long flags) 293 { 294 return clk_register_divider(NULL, name, parent, 295 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 296 reg, shift, width, 0, &imx_ccm_lock); 297 } 298 299 static inline struct clk *imx_clk_gate(const char *name, const char *parent, 300 void __iomem *reg, u8 shift) 301 { 302 return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 303 shift, 0, &imx_ccm_lock); 304 } 305 306 static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent, 307 void __iomem *reg, u8 shift, unsigned long flags) 308 { 309 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, 310 shift, 0, &imx_ccm_lock); 311 } 312 313 static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *parent, 314 void __iomem *reg, u8 shift) 315 { 316 return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 317 shift, 0, &imx_ccm_lock); 318 } 319 320 static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent, 321 void __iomem *reg, u8 shift) 322 { 323 return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 324 shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); 325 } 326 327 static inline struct clk_hw *imx_clk_hw_gate_dis_flags(const char *name, const char *parent, 328 void __iomem *reg, u8 shift, unsigned long flags) 329 { 330 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, 331 shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); 332 } 333 334 static inline struct clk_hw *imx_clk_hw_gate2(const char *name, const char *parent, 335 void __iomem *reg, u8 shift) 336 { 337 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 338 shift, 0x3, 0, &imx_ccm_lock, NULL); 339 } 340 341 static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent, 342 void __iomem *reg, u8 shift, unsigned long flags) 343 { 344 return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, 345 shift, 0x3, 0, &imx_ccm_lock, NULL); 346 } 347 348 static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name, 349 const char *parent, void __iomem *reg, u8 shift, 350 unsigned int *share_count) 351 { 352 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 353 shift, 0x3, 0, &imx_ccm_lock, share_count); 354 } 355 356 static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name, 357 const char *parent, void __iomem *reg, u8 shift, 358 unsigned int *share_count) 359 { 360 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | 361 CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, 362 &imx_ccm_lock, share_count); 363 } 364 365 static inline struct clk *imx_clk_gate2_cgr(const char *name, 366 const char *parent, void __iomem *reg, u8 shift, u8 cgr_val) 367 { 368 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 369 shift, cgr_val, 0, &imx_ccm_lock, NULL); 370 } 371 372 static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent, 373 void __iomem *reg, u8 shift) 374 { 375 return clk_hw_register_gate(NULL, name, parent, 376 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 377 reg, shift, 0, &imx_ccm_lock); 378 } 379 380 static inline struct clk *imx_clk_gate3_flags(const char *name, 381 const char *parent, void __iomem *reg, u8 shift, 382 unsigned long flags) 383 { 384 return clk_register_gate(NULL, name, parent, 385 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 386 reg, shift, 0, &imx_ccm_lock); 387 } 388 389 static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent, 390 void __iomem *reg, u8 shift) 391 { 392 return clk_hw_register_gate2(NULL, name, parent, 393 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 394 reg, shift, 0x3, 0, &imx_ccm_lock, NULL); 395 } 396 397 static inline struct clk *imx_clk_gate4_flags(const char *name, 398 const char *parent, void __iomem *reg, u8 shift, 399 unsigned long flags) 400 { 401 return clk_register_gate2(NULL, name, parent, 402 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 403 reg, shift, 0x3, 0, &imx_ccm_lock, NULL); 404 } 405 406 static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg, 407 u8 shift, u8 width, const char * const *parents, 408 int num_parents) 409 { 410 return clk_hw_register_mux(NULL, name, parents, num_parents, 411 CLK_SET_RATE_NO_REPARENT, reg, shift, 412 width, 0, &imx_ccm_lock); 413 } 414 415 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg, 416 u8 shift, u8 width, const char * const *parents, 417 int num_parents) 418 { 419 return clk_register_mux(NULL, name, parents, num_parents, 420 CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, 421 reg, shift, width, 0, &imx_ccm_lock); 422 } 423 424 static inline struct clk_hw *imx_clk_hw_mux2(const char *name, void __iomem *reg, 425 u8 shift, u8 width, 426 const char * const *parents, 427 int num_parents) 428 { 429 return clk_hw_register_mux(NULL, name, parents, num_parents, 430 CLK_SET_RATE_NO_REPARENT | 431 CLK_OPS_PARENT_ENABLE, 432 reg, shift, width, 0, &imx_ccm_lock); 433 } 434 435 static inline struct clk *imx_clk_mux_flags(const char *name, 436 void __iomem *reg, u8 shift, u8 width, 437 const char * const *parents, int num_parents, 438 unsigned long flags) 439 { 440 return clk_register_mux(NULL, name, parents, num_parents, 441 flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0, 442 &imx_ccm_lock); 443 } 444 445 static inline struct clk *imx_clk_mux2_flags(const char *name, 446 void __iomem *reg, u8 shift, u8 width, 447 const char * const *parents, 448 int num_parents, unsigned long flags) 449 { 450 return clk_register_mux(NULL, name, parents, num_parents, 451 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, 452 reg, shift, width, 0, &imx_ccm_lock); 453 } 454 455 static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name, 456 void __iomem *reg, u8 shift, 457 u8 width, 458 const char * const *parents, 459 int num_parents, 460 unsigned long flags) 461 { 462 return clk_hw_register_mux(NULL, name, parents, num_parents, 463 flags | CLK_SET_RATE_NO_REPARENT, 464 reg, shift, width, 0, &imx_ccm_lock); 465 } 466 467 struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, 468 struct clk *div, struct clk *mux, struct clk *pll, 469 struct clk *step); 470 471 struct clk *imx8m_clk_composite_flags(const char *name, 472 const char * const *parent_names, 473 int num_parents, void __iomem *reg, 474 unsigned long flags); 475 476 #define __imx8m_clk_composite(name, parent_names, reg, flags) \ 477 imx8m_clk_composite_flags(name, parent_names, \ 478 ARRAY_SIZE(parent_names), reg, \ 479 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) 480 481 #define imx8m_clk_composite(name, parent_names, reg) \ 482 __imx8m_clk_composite(name, parent_names, reg, 0) 483 484 #define imx8m_clk_composite_critical(name, parent_names, reg) \ 485 __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL) 486 487 struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name, 488 unsigned long flags, void __iomem *reg, u8 shift, u8 width, 489 u8 clk_divider_flags, const struct clk_div_table *table, 490 spinlock_t *lock); 491 #endif 492