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