Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
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 /* NOTE: Rate table should be kept sorted in descending order. */
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 /* NOTE: Rate table should be kept sorted in descending order. */
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