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