0001
0002 #ifndef __MACH_IMX_CLK_H
0003 #define __MACH_IMX_CLK_H
0004
0005 #include <linux/bits.h>
0006 #include <linux/spinlock.h>
0007 #include <linux/clk-provider.h>
0008
0009 extern spinlock_t imx_ccm_lock;
0010 extern bool mcore_booted;
0011
0012 void imx_check_clocks(struct clk *clks[], unsigned int count);
0013 void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
0014 #ifndef MODULE
0015 void imx_register_uart_clocks(unsigned int clk_count);
0016 #else
0017 static inline void imx_register_uart_clocks(unsigned int clk_count)
0018 {
0019 }
0020 #endif
0021 void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
0022 void imx_unregister_clocks(struct clk *clks[], unsigned int count);
0023 void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count);
0024
0025 extern void imx_cscmr1_fixup(u32 *val);
0026
0027 enum imx_pllv1_type {
0028 IMX_PLLV1_IMX1,
0029 IMX_PLLV1_IMX21,
0030 IMX_PLLV1_IMX25,
0031 IMX_PLLV1_IMX27,
0032 IMX_PLLV1_IMX31,
0033 IMX_PLLV1_IMX35,
0034 };
0035
0036 enum imx_sscg_pll_type {
0037 SCCG_PLL1,
0038 SCCG_PLL2,
0039 };
0040
0041 enum imx_pll14xx_type {
0042 PLL_1416X,
0043 PLL_1443X,
0044 };
0045
0046 enum imx_pllv4_type {
0047 IMX_PLLV4_IMX7ULP,
0048 IMX_PLLV4_IMX8ULP,
0049 };
0050
0051 enum imx_pfdv2_type {
0052 IMX_PFDV2_IMX7ULP,
0053 IMX_PFDV2_IMX8ULP,
0054 };
0055
0056
0057 struct imx_pll14xx_rate_table {
0058 unsigned int rate;
0059 unsigned int pdiv;
0060 unsigned int mdiv;
0061 unsigned int sdiv;
0062 unsigned int kdiv;
0063 };
0064
0065 struct imx_pll14xx_clk {
0066 enum imx_pll14xx_type type;
0067 const struct imx_pll14xx_rate_table *rate_table;
0068 int rate_count;
0069 int flags;
0070 };
0071
0072 extern struct imx_pll14xx_clk imx_1416x_pll;
0073 extern struct imx_pll14xx_clk imx_1443x_pll;
0074 extern struct imx_pll14xx_clk imx_1443x_dram_pll;
0075
0076
0077 struct imx_fracn_gppll_rate_table {
0078 unsigned int rate;
0079 unsigned int mfi;
0080 unsigned int mfn;
0081 unsigned int mfd;
0082 unsigned int rdiv;
0083 unsigned int odiv;
0084 };
0085
0086 struct imx_fracn_gppll_clk {
0087 const struct imx_fracn_gppll_rate_table *rate_table;
0088 int rate_count;
0089 int flags;
0090 };
0091
0092 struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
0093 const struct imx_fracn_gppll_clk *pll_clk);
0094
0095 extern struct imx_fracn_gppll_clk imx_fracn_gppll;
0096
0097 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
0098 to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
0099
0100 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
0101 cgr_val, cgr_mask, clk_gate_flags, lock, share_count) \
0102 to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
0103 cgr_val, cgr_mask, clk_gate_flags, lock, share_count))
0104
0105 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
0106 to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))
0107
0108 #define imx_clk_pfd(name, parent_name, reg, idx) \
0109 to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx))
0110
0111 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
0112 to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask))
0113
0114 #define imx_clk_fixed(name, rate) \
0115 to_clk(imx_clk_hw_fixed(name, rate))
0116
0117 #define imx_clk_fixed_factor(name, parent, mult, div) \
0118 to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div))
0119
0120 #define imx_clk_divider(name, parent, reg, shift, width) \
0121 to_clk(imx_clk_hw_divider(name, parent, reg, shift, width))
0122
0123 #define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \
0124 to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags))
0125
0126 #define imx_clk_gate(name, parent, reg, shift) \
0127 to_clk(imx_clk_hw_gate(name, parent, reg, shift))
0128
0129 #define imx_clk_gate_dis(name, parent, reg, shift) \
0130 to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift))
0131
0132 #define imx_clk_gate2(name, parent, reg, shift) \
0133 to_clk(imx_clk_hw_gate2(name, parent, reg, shift))
0134
0135 #define imx_clk_gate2_cgr(name, parent, reg, shift, cgr_val) \
0136 to_clk(__imx_clk_hw_gate2(name, parent, reg, shift, cgr_val, 0, NULL))
0137
0138 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
0139 to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags))
0140
0141 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
0142 to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents))
0143
0144 #define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \
0145 to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags))
0146
0147 #define imx_clk_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \
0148 to_clk(imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags))
0149
0150 #define imx_clk_pllv1(type, name, parent, base) \
0151 to_clk(imx_clk_hw_pllv1(type, name, parent, base))
0152
0153 #define imx_clk_pllv2(name, parent, base) \
0154 to_clk(imx_clk_hw_pllv2(name, parent, base))
0155
0156 #define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \
0157 to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags))
0158
0159 #define imx_clk_hw_gate(name, parent, reg, shift) \
0160 imx_clk_hw_gate_flags(name, parent, reg, shift, 0)
0161
0162 #define imx_clk_hw_gate2(name, parent, reg, shift) \
0163 imx_clk_hw_gate2_flags(name, parent, reg, shift, 0)
0164
0165 #define imx_clk_hw_gate_dis(name, parent, reg, shift) \
0166 imx_clk_hw_gate_dis_flags(name, parent, reg, shift, 0)
0167
0168 #define imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags) \
0169 __imx_clk_hw_gate(name, parent, reg, shift, flags, CLK_GATE_SET_TO_DISABLE)
0170
0171 #define imx_clk_hw_gate_flags(name, parent, reg, shift, flags) \
0172 __imx_clk_hw_gate(name, parent, reg, shift, flags, 0)
0173
0174 #define imx_clk_hw_gate2_flags(name, parent, reg, shift, flags) \
0175 __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, flags, NULL)
0176
0177 #define imx_clk_hw_gate2_shared(name, parent, reg, shift, shared_count) \
0178 __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, 0, shared_count)
0179
0180 #define imx_clk_hw_gate2_shared2(name, parent, reg, shift, shared_count) \
0181 __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, CLK_OPS_PARENT_ENABLE, shared_count)
0182
0183 #define imx_clk_hw_gate3(name, parent, reg, shift) \
0184 imx_clk_hw_gate3_flags(name, parent, reg, shift, 0)
0185
0186 #define imx_clk_hw_gate3_flags(name, parent, reg, shift, flags) \
0187 __imx_clk_hw_gate(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE, 0)
0188
0189 #define imx_clk_hw_gate4(name, parent, reg, shift) \
0190 imx_clk_hw_gate4_flags(name, parent, reg, shift, 0)
0191
0192 #define imx_clk_hw_gate4_flags(name, parent, reg, shift, flags) \
0193 imx_clk_hw_gate2_flags(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE)
0194
0195 #define imx_clk_hw_mux2(name, reg, shift, width, parents, num_parents) \
0196 imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, 0)
0197
0198 #define imx_clk_hw_mux(name, reg, shift, width, parents, num_parents) \
0199 __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, 0, 0)
0200
0201 #define imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags) \
0202 __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags, 0)
0203
0204 #define imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents) \
0205 __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT, CLK_MUX_READ_ONLY)
0206
0207 #define imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \
0208 __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags | CLK_OPS_PARENT_ENABLE, 0)
0209
0210 #define imx_clk_hw_divider(name, parent, reg, shift, width) \
0211 __imx_clk_hw_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT)
0212
0213 #define imx_clk_hw_divider2(name, parent, reg, shift, width) \
0214 __imx_clk_hw_divider(name, parent, reg, shift, width, \
0215 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE)
0216
0217 #define imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags) \
0218 __imx_clk_hw_divider(name, parent, reg, shift, width, flags)
0219
0220 #define imx_clk_hw_pll14xx(name, parent_name, base, pll_clk) \
0221 imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk)
0222
0223 struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
0224 const char *parent_name, void __iomem *base,
0225 const struct imx_pll14xx_clk *pll_clk);
0226
0227 struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
0228 const char *parent, void __iomem *base);
0229
0230 struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent,
0231 void __iomem *base);
0232
0233 struct clk_hw *imx_clk_hw_frac_pll(const char *name, const char *parent_name,
0234 void __iomem *base);
0235
0236 struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
0237 const char * const *parent_names,
0238 u8 num_parents,
0239 u8 parent, u8 bypass1, u8 bypass2,
0240 void __iomem *base,
0241 unsigned long flags);
0242
0243 enum imx_pllv3_type {
0244 IMX_PLLV3_GENERIC,
0245 IMX_PLLV3_SYS,
0246 IMX_PLLV3_USB,
0247 IMX_PLLV3_USB_VF610,
0248 IMX_PLLV3_AV,
0249 IMX_PLLV3_ENET,
0250 IMX_PLLV3_ENET_IMX7,
0251 IMX_PLLV3_SYS_VF610,
0252 IMX_PLLV3_DDR_IMX7,
0253 IMX_PLLV3_AV_IMX7,
0254 };
0255
0256 struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
0257 const char *parent_name, void __iomem *base, u32 div_mask);
0258
0259 #define PLL_1416X_RATE(_rate, _m, _p, _s) \
0260 { \
0261 .rate = (_rate), \
0262 .mdiv = (_m), \
0263 .pdiv = (_p), \
0264 .sdiv = (_s), \
0265 }
0266
0267 #define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
0268 { \
0269 .rate = (_rate), \
0270 .mdiv = (_m), \
0271 .pdiv = (_p), \
0272 .sdiv = (_s), \
0273 .kdiv = (_k), \
0274 }
0275
0276 struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name,
0277 const char *parent_name, void __iomem *base);
0278
0279 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
0280 const char *parent_name, unsigned long flags,
0281 void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 cgr_mask,
0282 u8 clk_gate_flags, spinlock_t *lock,
0283 unsigned int *share_count);
0284
0285 struct clk * imx_obtain_fixed_clock(
0286 const char *name, unsigned long rate);
0287
0288 struct clk_hw *imx_obtain_fixed_clock_hw(
0289 const char *name, unsigned long rate);
0290
0291 struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np,
0292 const char *name);
0293
0294 struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
0295 void __iomem *reg, u8 shift, u32 exclusive_mask);
0296
0297 struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name,
0298 void __iomem *reg, u8 idx);
0299
0300 struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name,
0301 const char *parent_name, void __iomem *reg, u8 idx);
0302
0303 struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name,
0304 void __iomem *reg, u8 shift, u8 width,
0305 void __iomem *busy_reg, u8 busy_shift);
0306
0307 struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift,
0308 u8 width, void __iomem *busy_reg, u8 busy_shift,
0309 const char * const *parent_names, int num_parents);
0310
0311 struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
0312 const char * const *parent_names,
0313 int num_parents, bool mux_present,
0314 bool rate_present, bool gate_present,
0315 void __iomem *reg);
0316
0317 struct clk_hw *imx8ulp_clk_hw_composite(const char *name,
0318 const char * const *parent_names,
0319 int num_parents, bool mux_present,
0320 bool rate_present, bool gate_present,
0321 void __iomem *reg, bool has_swrst);
0322
0323 struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent,
0324 void __iomem *reg, u8 shift, u8 width,
0325 void (*fixup)(u32 *val));
0326
0327 struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg,
0328 u8 shift, u8 width, const char * const *parents,
0329 int num_parents, void (*fixup)(u32 *val));
0330
0331 static inline struct clk *to_clk(struct clk_hw *hw)
0332 {
0333 if (IS_ERR_OR_NULL(hw))
0334 return ERR_CAST(hw);
0335 return hw->clk;
0336 }
0337
0338 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
0339 {
0340 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
0341 }
0342
0343 static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name,
0344 const char *parent, unsigned int mult, unsigned int div)
0345 {
0346 return clk_hw_register_fixed_factor(NULL, name, parent,
0347 CLK_SET_RATE_PARENT, mult, div);
0348 }
0349
0350 static inline struct clk_hw *__imx_clk_hw_divider(const char *name,
0351 const char *parent,
0352 void __iomem *reg, u8 shift,
0353 u8 width, unsigned long flags)
0354 {
0355 return clk_hw_register_divider(NULL, name, parent, flags,
0356 reg, shift, width, 0, &imx_ccm_lock);
0357 }
0358
0359 static inline struct clk_hw *__imx_clk_hw_gate(const char *name, const char *parent,
0360 void __iomem *reg, u8 shift,
0361 unsigned long flags,
0362 unsigned long clk_gate_flags)
0363 {
0364 return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
0365 shift, clk_gate_flags, &imx_ccm_lock);
0366 }
0367
0368 static inline struct clk_hw *__imx_clk_hw_gate2(const char *name, const char *parent,
0369 void __iomem *reg, u8 shift, u8 cgr_val,
0370 unsigned long flags,
0371 unsigned int *share_count)
0372 {
0373 return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
0374 shift, cgr_val, 0x3, 0, &imx_ccm_lock, share_count);
0375 }
0376
0377 static inline struct clk_hw *__imx_clk_hw_mux(const char *name, void __iomem *reg,
0378 u8 shift, u8 width, const char * const *parents,
0379 int num_parents, unsigned long flags, unsigned long clk_mux_flags)
0380 {
0381 return clk_hw_register_mux(NULL, name, parents, num_parents,
0382 flags | CLK_SET_RATE_NO_REPARENT, reg, shift,
0383 width, clk_mux_flags, &imx_ccm_lock);
0384 }
0385
0386 struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
0387 struct clk *div, struct clk *mux, struct clk *pll,
0388 struct clk *step);
0389
0390 #define IMX_COMPOSITE_CORE BIT(0)
0391 #define IMX_COMPOSITE_BUS BIT(1)
0392 #define IMX_COMPOSITE_FW_MANAGED BIT(2)
0393
0394 #define IMX_COMPOSITE_CLK_FLAGS_DEFAULT \
0395 (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
0396 #define IMX_COMPOSITE_CLK_FLAGS_CRITICAL \
0397 (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_IS_CRITICAL)
0398 #define IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE \
0399 (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_GET_RATE_NOCACHE)
0400 #define IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE \
0401 (IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE | CLK_IS_CRITICAL)
0402
0403 struct clk_hw *__imx8m_clk_hw_composite(const char *name,
0404 const char * const *parent_names,
0405 int num_parents,
0406 void __iomem *reg,
0407 u32 composite_flags,
0408 unsigned long flags);
0409
0410 #define _imx8m_clk_hw_composite(name, parent_names, reg, composite_flags, flags) \
0411 __imx8m_clk_hw_composite(name, parent_names, \
0412 ARRAY_SIZE(parent_names), reg, composite_flags, flags)
0413
0414 #define imx8m_clk_hw_composite(name, parent_names, reg) \
0415 _imx8m_clk_hw_composite(name, parent_names, reg, \
0416 0, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
0417
0418 #define imx8m_clk_hw_composite_critical(name, parent_names, reg) \
0419 _imx8m_clk_hw_composite(name, parent_names, reg, \
0420 0, IMX_COMPOSITE_CLK_FLAGS_CRITICAL)
0421
0422 #define imx8m_clk_hw_composite_bus(name, parent_names, reg) \
0423 _imx8m_clk_hw_composite(name, parent_names, reg, \
0424 IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
0425
0426 #define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \
0427 _imx8m_clk_hw_composite(name, parent_names, reg, \
0428 IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_CRITICAL)
0429
0430 #define imx8m_clk_hw_composite_core(name, parent_names, reg) \
0431 _imx8m_clk_hw_composite(name, parent_names, reg, \
0432 IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
0433
0434 #define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
0435 _imx8m_clk_hw_composite(name, parent_names, reg, \
0436 IMX_COMPOSITE_FW_MANAGED, \
0437 IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE)
0438
0439 #define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
0440 _imx8m_clk_hw_composite(name, parent_names, reg, \
0441 IMX_COMPOSITE_FW_MANAGED, \
0442 IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE)
0443
0444 struct clk_hw *imx93_clk_composite_flags(const char *name,
0445 const char * const *parent_names,
0446 int num_parents,
0447 void __iomem *reg,
0448 unsigned long flags);
0449 #define imx93_clk_composite(name, parent_names, num_parents, reg) \
0450 imx93_clk_composite_flags(name, parent_names, num_parents, reg, \
0451 CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
0452
0453 struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
0454 unsigned long flags, void __iomem *reg, u8 shift, u8 width,
0455 u8 clk_divider_flags, const struct clk_div_table *table,
0456 spinlock_t *lock);
0457 #endif