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