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_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn); 14 void imx_unregister_clocks(struct clk *clks[], unsigned int count); 15 void imx_unregister_hw_clocks(struct clk_hw *hws[], 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_sscg_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 extern struct imx_pll14xx_clk imx_1416x_pll; 55 extern struct imx_pll14xx_clk imx_1443x_pll; 56 extern struct imx_pll14xx_clk imx_1443x_dram_pll; 57 58 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ 59 to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)) 60 61 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ 62 cgr_val, clk_gate_flags, lock, share_count) \ 63 to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ 64 cgr_val, clk_gate_flags, lock, share_count)) 65 66 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \ 67 to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)) 68 69 #define imx_clk_pfd(name, parent_name, reg, idx) \ 70 to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx)) 71 72 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \ 73 to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)) 74 75 #define imx_clk_fixed(name, rate) \ 76 to_clk(imx_clk_hw_fixed(name, rate)) 77 78 #define imx_clk_fixed_factor(name, parent, mult, div) \ 79 to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div)) 80 81 #define imx_clk_divider(name, parent, reg, shift, width) \ 82 to_clk(imx_clk_hw_divider(name, parent, reg, shift, width)) 83 84 #define imx_clk_divider2(name, parent, reg, shift, width) \ 85 to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width)) 86 87 #define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \ 88 to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags)) 89 90 #define imx_clk_gate(name, parent, reg, shift) \ 91 to_clk(imx_clk_hw_gate(name, parent, reg, shift)) 92 93 #define imx_clk_gate_dis(name, parent, reg, shift) \ 94 to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift)) 95 96 #define imx_clk_gate2(name, parent, reg, shift) \ 97 to_clk(imx_clk_hw_gate2(name, parent, reg, shift)) 98 99 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \ 100 to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)) 101 102 #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \ 103 to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)) 104 105 #define imx_clk_gate3(name, parent, reg, shift) \ 106 to_clk(imx_clk_hw_gate3(name, parent, reg, shift)) 107 108 #define imx_clk_gate4(name, parent, reg, shift) \ 109 to_clk(imx_clk_hw_gate4(name, parent, reg, shift)) 110 111 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \ 112 to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)) 113 114 #define imx_clk_pllv1(type, name, parent, base) \ 115 to_clk(imx_clk_hw_pllv1(type, name, parent, base)) 116 117 #define imx_clk_pllv2(name, parent, base) \ 118 to_clk(imx_clk_hw_pllv2(name, parent, base)) 119 120 #define imx_clk_frac_pll(name, parent_name, base) \ 121 to_clk(imx_clk_hw_frac_pll(name, parent_name, base)) 122 123 #define imx_clk_sscg_pll(name, parent_names, num_parents, parent,\ 124 bypass1, bypass2, base, flags) \ 125 to_clk(imx_clk_hw_sscg_pll(name, parent_names, num_parents, parent,\ 126 bypass1, bypass2, base, flags)) 127 128 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, 129 void __iomem *base, const struct imx_pll14xx_clk *pll_clk); 130 131 #define imx_clk_pll14xx(name, parent_name, base, pll_clk) \ 132 to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk)) 133 134 struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name, 135 void __iomem *base, 136 const struct imx_pll14xx_clk *pll_clk); 137 138 struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name, 139 const char *parent, void __iomem *base); 140 141 struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent, 142 void __iomem *base); 143 144 struct clk_hw *imx_clk_hw_frac_pll(const char *name, const char *parent_name, 145 void __iomem *base); 146 147 struct clk_hw *imx_clk_hw_sscg_pll(const char *name, 148 const char * const *parent_names, 149 u8 num_parents, 150 u8 parent, u8 bypass1, u8 bypass2, 151 void __iomem *base, 152 unsigned long flags); 153 154 enum imx_pllv3_type { 155 IMX_PLLV3_GENERIC, 156 IMX_PLLV3_SYS, 157 IMX_PLLV3_USB, 158 IMX_PLLV3_USB_VF610, 159 IMX_PLLV3_AV, 160 IMX_PLLV3_ENET, 161 IMX_PLLV3_ENET_IMX7, 162 IMX_PLLV3_SYS_VF610, 163 IMX_PLLV3_DDR_IMX7, 164 IMX_PLLV3_AV_IMX7, 165 }; 166 167 struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, 168 const char *parent_name, void __iomem *base, u32 div_mask); 169 170 #define PLL_1416X_RATE(_rate, _m, _p, _s) \ 171 { \ 172 .rate = (_rate), \ 173 .mdiv = (_m), \ 174 .pdiv = (_p), \ 175 .sdiv = (_s), \ 176 } 177 178 #define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \ 179 { \ 180 .rate = (_rate), \ 181 .mdiv = (_m), \ 182 .pdiv = (_p), \ 183 .sdiv = (_s), \ 184 .kdiv = (_k), \ 185 } 186 187 struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name, 188 void __iomem *base); 189 190 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, 191 const char *parent_name, unsigned long flags, 192 void __iomem *reg, u8 bit_idx, u8 cgr_val, 193 u8 clk_gate_flags, spinlock_t *lock, 194 unsigned int *share_count); 195 196 struct clk * imx_obtain_fixed_clock( 197 const char *name, unsigned long rate); 198 199 struct clk_hw *imx_obtain_fixed_clock_hw( 200 const char *name, unsigned long rate); 201 202 struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np, 203 const char *name); 204 205 struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, 206 void __iomem *reg, u8 shift, u32 exclusive_mask); 207 208 struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, 209 void __iomem *reg, u8 idx); 210 211 struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, 212 void __iomem *reg, u8 idx); 213 214 struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name, 215 void __iomem *reg, u8 shift, u8 width, 216 void __iomem *busy_reg, u8 busy_shift); 217 218 struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift, 219 u8 width, void __iomem *busy_reg, u8 busy_shift, 220 const char * const *parent_names, int num_parents); 221 222 struct clk_hw *imx7ulp_clk_hw_composite(const char *name, 223 const char * const *parent_names, 224 int num_parents, bool mux_present, 225 bool rate_present, bool gate_present, 226 void __iomem *reg); 227 228 struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, 229 void __iomem *reg, u8 shift, u8 width, 230 void (*fixup)(u32 *val)); 231 232 struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg, 233 u8 shift, u8 width, const char * const *parents, 234 int num_parents, void (*fixup)(u32 *val)); 235 236 static inline struct clk *to_clk(struct clk_hw *hw) 237 { 238 if (IS_ERR_OR_NULL(hw)) 239 return ERR_CAST(hw); 240 return hw->clk; 241 } 242 243 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate) 244 { 245 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); 246 } 247 248 static inline struct clk_hw *imx_clk_hw_mux_ldb(const char *name, void __iomem *reg, 249 u8 shift, u8 width, const char * const *parents, 250 int num_parents) 251 { 252 return clk_hw_register_mux(NULL, name, parents, num_parents, 253 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg, 254 shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock); 255 } 256 257 static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name, 258 const char *parent, unsigned int mult, unsigned int div) 259 { 260 return clk_hw_register_fixed_factor(NULL, name, parent, 261 CLK_SET_RATE_PARENT, mult, div); 262 } 263 264 static inline struct clk_hw *imx_clk_hw_divider(const char *name, 265 const char *parent, 266 void __iomem *reg, u8 shift, 267 u8 width) 268 { 269 return clk_hw_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, 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_hw *imx_clk_hw_gate_flags(const char *name, const char *parent, 300 void __iomem *reg, u8 shift, unsigned long flags) 301 { 302 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, 303 shift, 0, &imx_ccm_lock); 304 } 305 306 static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *parent, 307 void __iomem *reg, u8 shift) 308 { 309 return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 310 shift, 0, &imx_ccm_lock); 311 } 312 313 static inline struct clk_hw *imx_clk_hw_gate_dis(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, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); 318 } 319 320 static inline struct clk_hw *imx_clk_hw_gate_dis_flags(const char *name, const char *parent, 321 void __iomem *reg, u8 shift, unsigned long flags) 322 { 323 return clk_hw_register_gate(NULL, name, parent, flags | 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_gate2(const char *name, const char *parent, 328 void __iomem *reg, u8 shift) 329 { 330 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 331 shift, 0x3, 0, &imx_ccm_lock, NULL); 332 } 333 334 static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent, 335 void __iomem *reg, u8 shift, unsigned long flags) 336 { 337 return clk_hw_register_gate2(NULL, name, parent, flags | 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_shared(const char *name, 342 const char *parent, void __iomem *reg, u8 shift, 343 unsigned int *share_count) 344 { 345 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 346 shift, 0x3, 0, &imx_ccm_lock, share_count); 347 } 348 349 static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name, 350 const char *parent, void __iomem *reg, u8 shift, 351 unsigned int *share_count) 352 { 353 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | 354 CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, 355 &imx_ccm_lock, share_count); 356 } 357 358 static inline struct clk *imx_clk_gate2_cgr(const char *name, 359 const char *parent, void __iomem *reg, u8 shift, u8 cgr_val) 360 { 361 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 362 shift, cgr_val, 0, &imx_ccm_lock, NULL); 363 } 364 365 static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent, 366 void __iomem *reg, u8 shift) 367 { 368 return clk_hw_register_gate(NULL, name, parent, 369 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 370 reg, shift, 0, &imx_ccm_lock); 371 } 372 373 static inline struct clk_hw *imx_clk_hw_gate3_flags(const char *name, 374 const char *parent, void __iomem *reg, u8 shift, 375 unsigned long flags) 376 { 377 return clk_hw_register_gate(NULL, name, parent, 378 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 379 reg, shift, 0, &imx_ccm_lock); 380 } 381 382 #define imx_clk_gate3_flags(name, parent, reg, shift, flags) \ 383 to_clk(imx_clk_hw_gate3_flags(name, parent, reg, shift, flags)) 384 385 static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent, 386 void __iomem *reg, u8 shift) 387 { 388 return clk_hw_register_gate2(NULL, name, parent, 389 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 390 reg, shift, 0x3, 0, &imx_ccm_lock, NULL); 391 } 392 393 static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name, 394 const char *parent, void __iomem *reg, u8 shift, 395 unsigned long flags) 396 { 397 return clk_hw_register_gate2(NULL, name, parent, 398 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 399 reg, shift, 0x3, 0, &imx_ccm_lock, NULL); 400 } 401 402 #define imx_clk_gate4_flags(name, parent, reg, shift, flags) \ 403 to_clk(imx_clk_hw_gate4_flags(name, parent, reg, shift, flags)) 404 405 static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg, 406 u8 shift, u8 width, const char * const *parents, 407 int num_parents) 408 { 409 return clk_hw_register_mux(NULL, name, parents, num_parents, 410 CLK_SET_RATE_NO_REPARENT, reg, shift, 411 width, 0, &imx_ccm_lock); 412 } 413 414 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg, 415 u8 shift, u8 width, const char * const *parents, 416 int num_parents) 417 { 418 return clk_register_mux(NULL, name, parents, num_parents, 419 CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, 420 reg, shift, width, 0, &imx_ccm_lock); 421 } 422 423 static inline struct clk_hw *imx_clk_hw_mux2(const char *name, void __iomem *reg, 424 u8 shift, u8 width, 425 const char * const *parents, 426 int num_parents) 427 { 428 return clk_hw_register_mux(NULL, name, parents, num_parents, 429 CLK_SET_RATE_NO_REPARENT | 430 CLK_OPS_PARENT_ENABLE, 431 reg, shift, width, 0, &imx_ccm_lock); 432 } 433 434 static inline struct clk *imx_clk_mux_flags(const char *name, 435 void __iomem *reg, u8 shift, u8 width, 436 const char * const *parents, int num_parents, 437 unsigned long flags) 438 { 439 return clk_register_mux(NULL, name, parents, num_parents, 440 flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0, 441 &imx_ccm_lock); 442 } 443 444 static inline struct clk_hw *imx_clk_hw_mux2_flags(const char *name, 445 void __iomem *reg, u8 shift, u8 width, 446 const char * const *parents, 447 int num_parents, unsigned long flags) 448 { 449 return clk_hw_register_mux(NULL, name, parents, num_parents, 450 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, 451 reg, shift, width, 0, &imx_ccm_lock); 452 } 453 454 static inline struct clk *imx_clk_mux2_flags(const char *name, 455 void __iomem *reg, u8 shift, u8 width, 456 const char * const *parents, 457 int num_parents, unsigned long flags) 458 { 459 return clk_register_mux(NULL, name, parents, num_parents, 460 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, 461 reg, shift, width, 0, &imx_ccm_lock); 462 } 463 464 static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name, 465 void __iomem *reg, u8 shift, 466 u8 width, 467 const char * const *parents, 468 int num_parents, 469 unsigned long flags) 470 { 471 return clk_hw_register_mux(NULL, name, parents, num_parents, 472 flags | CLK_SET_RATE_NO_REPARENT, 473 reg, shift, width, 0, &imx_ccm_lock); 474 } 475 476 struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, 477 struct clk *div, struct clk *mux, struct clk *pll, 478 struct clk *step); 479 480 #define IMX_COMPOSITE_CORE BIT(0) 481 482 struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, 483 const char * const *parent_names, 484 int num_parents, 485 void __iomem *reg, 486 u32 composite_flags, 487 unsigned long flags); 488 489 #define imx8m_clk_hw_composite_core(name, parent_names, reg) \ 490 imx8m_clk_hw_composite_flags(name, parent_names, \ 491 ARRAY_SIZE(parent_names), reg, \ 492 IMX_COMPOSITE_CORE, \ 493 CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) 494 495 #define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \ 496 flags) \ 497 to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \ 498 num_parents, reg, 0, flags)) 499 500 #define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \ 501 imx8m_clk_hw_composite_flags(name, parent_names, \ 502 ARRAY_SIZE(parent_names), reg, 0, \ 503 flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) 504 505 #define __imx8m_clk_composite(name, parent_names, reg, flags) \ 506 to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags)) 507 508 #define imx8m_clk_hw_composite(name, parent_names, reg) \ 509 __imx8m_clk_hw_composite(name, parent_names, reg, 0) 510 511 #define imx8m_clk_composite(name, parent_names, reg) \ 512 __imx8m_clk_composite(name, parent_names, reg, 0) 513 514 #define imx8m_clk_hw_composite_critical(name, parent_names, reg) \ 515 __imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL) 516 517 #define imx8m_clk_composite_critical(name, parent_names, reg) \ 518 __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL) 519 520 struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name, 521 unsigned long flags, void __iomem *reg, u8 shift, u8 width, 522 u8 clk_divider_flags, const struct clk_div_table *table, 523 spinlock_t *lock); 524 #endif 525