1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 26b63f023SChao Xie #ifndef __MACH_MMP_CLK_H 36b63f023SChao Xie #define __MACH_MMP_CLK_H 46b63f023SChao Xie 56b63f023SChao Xie #include <linux/clk-provider.h> 6*ee4df236SLubomir Rintel #include <linux/pm_domain.h> 76b63f023SChao Xie #include <linux/clkdev.h> 86b63f023SChao Xie 96b63f023SChao Xie #define APBC_NO_BUS_CTRL BIT(0) 106b63f023SChao Xie #define APBC_POWER_CTRL BIT(1) 116b63f023SChao Xie 123a2b2f84SChao Xie 133a2b2f84SChao Xie /* Clock type "factor" */ 142bd1e256SChao Xie struct mmp_clk_factor_masks { 156b63f023SChao Xie unsigned int factor; 166b63f023SChao Xie unsigned int num_mask; 176b63f023SChao Xie unsigned int den_mask; 186b63f023SChao Xie unsigned int num_shift; 196b63f023SChao Xie unsigned int den_shift; 205278acc4SLubomir Rintel unsigned int enable_mask; 216b63f023SChao Xie }; 226b63f023SChao Xie 232bd1e256SChao Xie struct mmp_clk_factor_tbl { 246b63f023SChao Xie unsigned int num; 256b63f023SChao Xie unsigned int den; 266b63f023SChao Xie }; 276b63f023SChao Xie 283a2b2f84SChao Xie struct mmp_clk_factor { 293a2b2f84SChao Xie struct clk_hw hw; 303a2b2f84SChao Xie void __iomem *base; 313a2b2f84SChao Xie struct mmp_clk_factor_masks *masks; 323a2b2f84SChao Xie struct mmp_clk_factor_tbl *ftbl; 333a2b2f84SChao Xie unsigned int ftbl_cnt; 343a2b2f84SChao Xie spinlock_t *lock; 353a2b2f84SChao Xie }; 363a2b2f84SChao Xie 373a2b2f84SChao Xie extern struct clk *mmp_clk_register_factor(const char *name, 383a2b2f84SChao Xie const char *parent_name, unsigned long flags, 393a2b2f84SChao Xie void __iomem *base, struct mmp_clk_factor_masks *masks, 403a2b2f84SChao Xie struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt, 413a2b2f84SChao Xie spinlock_t *lock); 423a2b2f84SChao Xie 43ee81f4eeSChao Xie /* Clock type "mix" */ 44ee81f4eeSChao Xie #define MMP_CLK_BITS_MASK(width, shift) \ 45ee81f4eeSChao Xie (((1 << (width)) - 1) << (shift)) 46ee81f4eeSChao Xie #define MMP_CLK_BITS_GET_VAL(data, width, shift) \ 47ee81f4eeSChao Xie ((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift)) 48ee81f4eeSChao Xie #define MMP_CLK_BITS_SET_VAL(val, width, shift) \ 49ee81f4eeSChao Xie (((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift)) 50ee81f4eeSChao Xie 51ee81f4eeSChao Xie enum { 52ee81f4eeSChao Xie MMP_CLK_MIX_TYPE_V1, 53ee81f4eeSChao Xie MMP_CLK_MIX_TYPE_V2, 54ee81f4eeSChao Xie MMP_CLK_MIX_TYPE_V3, 55ee81f4eeSChao Xie }; 56ee81f4eeSChao Xie 57ee81f4eeSChao Xie /* The register layout */ 58ee81f4eeSChao Xie struct mmp_clk_mix_reg_info { 59ee81f4eeSChao Xie void __iomem *reg_clk_ctrl; 60ee81f4eeSChao Xie void __iomem *reg_clk_sel; 61ee81f4eeSChao Xie u8 width_div; 62ee81f4eeSChao Xie u8 shift_div; 63ee81f4eeSChao Xie u8 width_mux; 64ee81f4eeSChao Xie u8 shift_mux; 65ee81f4eeSChao Xie u8 bit_fc; 66ee81f4eeSChao Xie }; 67ee81f4eeSChao Xie 68ee81f4eeSChao Xie /* The suggested clock table from user. */ 69ee81f4eeSChao Xie struct mmp_clk_mix_clk_table { 70ee81f4eeSChao Xie unsigned long rate; 71ee81f4eeSChao Xie u8 parent_index; 72ee81f4eeSChao Xie unsigned int divisor; 73ee81f4eeSChao Xie unsigned int valid; 74ee81f4eeSChao Xie }; 75ee81f4eeSChao Xie 76ee81f4eeSChao Xie struct mmp_clk_mix_config { 77ee81f4eeSChao Xie struct mmp_clk_mix_reg_info reg_info; 78ee81f4eeSChao Xie struct mmp_clk_mix_clk_table *table; 79ee81f4eeSChao Xie unsigned int table_size; 80ee81f4eeSChao Xie u32 *mux_table; 81ee81f4eeSChao Xie struct clk_div_table *div_table; 82ee81f4eeSChao Xie u8 div_flags; 83ee81f4eeSChao Xie u8 mux_flags; 84ee81f4eeSChao Xie }; 85ee81f4eeSChao Xie 86ee81f4eeSChao Xie struct mmp_clk_mix { 87ee81f4eeSChao Xie struct clk_hw hw; 88ee81f4eeSChao Xie struct mmp_clk_mix_reg_info reg_info; 89ee81f4eeSChao Xie struct mmp_clk_mix_clk_table *table; 90ee81f4eeSChao Xie u32 *mux_table; 91ee81f4eeSChao Xie struct clk_div_table *div_table; 92ee81f4eeSChao Xie unsigned int table_size; 93ee81f4eeSChao Xie u8 div_flags; 94ee81f4eeSChao Xie u8 mux_flags; 95ee81f4eeSChao Xie unsigned int type; 96ee81f4eeSChao Xie spinlock_t *lock; 97ee81f4eeSChao Xie }; 98ee81f4eeSChao Xie 99ee81f4eeSChao Xie extern const struct clk_ops mmp_clk_mix_ops; 100ee81f4eeSChao Xie extern struct clk *mmp_clk_register_mix(struct device *dev, 101ee81f4eeSChao Xie const char *name, 102cb8dbfe8SLubomir Rintel const char * const *parent_names, 1034661fda1SChao Xie u8 num_parents, 104ee81f4eeSChao Xie unsigned long flags, 105ee81f4eeSChao Xie struct mmp_clk_mix_config *config, 106ee81f4eeSChao Xie spinlock_t *lock); 107ee81f4eeSChao Xie 108ee81f4eeSChao Xie 109cdce3546SChao Xie /* Clock type "gate". MMP private gate */ 110cdce3546SChao Xie #define MMP_CLK_GATE_NEED_DELAY BIT(0) 111cdce3546SChao Xie 112cdce3546SChao Xie struct mmp_clk_gate { 113cdce3546SChao Xie struct clk_hw hw; 114cdce3546SChao Xie void __iomem *reg; 115cdce3546SChao Xie u32 mask; 116cdce3546SChao Xie u32 val_enable; 117cdce3546SChao Xie u32 val_disable; 118cdce3546SChao Xie unsigned int flags; 119cdce3546SChao Xie spinlock_t *lock; 120cdce3546SChao Xie }; 121cdce3546SChao Xie 122cdce3546SChao Xie extern const struct clk_ops mmp_clk_gate_ops; 123cdce3546SChao Xie extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name, 124cdce3546SChao Xie const char *parent_name, unsigned long flags, 125cdce3546SChao Xie void __iomem *reg, u32 mask, u32 val_enable, 126cdce3546SChao Xie u32 val_disable, unsigned int gate_flags, 127cdce3546SChao Xie spinlock_t *lock); 128cdce3546SChao Xie 1296b63f023SChao Xie extern struct clk *mmp_clk_register_apbc(const char *name, 1306b63f023SChao Xie const char *parent_name, void __iomem *base, 1316b63f023SChao Xie unsigned int delay, unsigned int apbc_flags, spinlock_t *lock); 1326b63f023SChao Xie extern struct clk *mmp_clk_register_apmu(const char *name, 1336b63f023SChao Xie const char *parent_name, void __iomem *base, u32 enable_mask, 1346b63f023SChao Xie spinlock_t *lock); 1354661fda1SChao Xie 1364661fda1SChao Xie struct mmp_clk_unit { 1374661fda1SChao Xie unsigned int nr_clks; 1384661fda1SChao Xie struct clk **clk_table; 1394661fda1SChao Xie struct clk_onecell_data clk_data; 1404661fda1SChao Xie }; 1414661fda1SChao Xie 1424661fda1SChao Xie struct mmp_param_fixed_rate_clk { 1434661fda1SChao Xie unsigned int id; 1444661fda1SChao Xie char *name; 1454661fda1SChao Xie const char *parent_name; 1464661fda1SChao Xie unsigned long flags; 1474661fda1SChao Xie unsigned long fixed_rate; 1484661fda1SChao Xie }; 1494661fda1SChao Xie void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit, 1504661fda1SChao Xie struct mmp_param_fixed_rate_clk *clks, 1514661fda1SChao Xie int size); 1524661fda1SChao Xie 1534661fda1SChao Xie struct mmp_param_fixed_factor_clk { 1544661fda1SChao Xie unsigned int id; 1554661fda1SChao Xie char *name; 1564661fda1SChao Xie const char *parent_name; 1574661fda1SChao Xie unsigned long mult; 1584661fda1SChao Xie unsigned long div; 1594661fda1SChao Xie unsigned long flags; 1604661fda1SChao Xie }; 1614661fda1SChao Xie void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit, 1624661fda1SChao Xie struct mmp_param_fixed_factor_clk *clks, 1634661fda1SChao Xie int size); 1644661fda1SChao Xie 1654661fda1SChao Xie struct mmp_param_general_gate_clk { 1664661fda1SChao Xie unsigned int id; 1674661fda1SChao Xie const char *name; 1684661fda1SChao Xie const char *parent_name; 1694661fda1SChao Xie unsigned long flags; 1704661fda1SChao Xie unsigned long offset; 1714661fda1SChao Xie u8 bit_idx; 1724661fda1SChao Xie u8 gate_flags; 1734661fda1SChao Xie spinlock_t *lock; 1744661fda1SChao Xie }; 1754661fda1SChao Xie void mmp_register_general_gate_clks(struct mmp_clk_unit *unit, 1764661fda1SChao Xie struct mmp_param_general_gate_clk *clks, 1774661fda1SChao Xie void __iomem *base, int size); 1784661fda1SChao Xie 1794661fda1SChao Xie struct mmp_param_gate_clk { 1804661fda1SChao Xie unsigned int id; 1814661fda1SChao Xie char *name; 1824661fda1SChao Xie const char *parent_name; 1834661fda1SChao Xie unsigned long flags; 1844661fda1SChao Xie unsigned long offset; 1854661fda1SChao Xie u32 mask; 1864661fda1SChao Xie u32 val_enable; 1874661fda1SChao Xie u32 val_disable; 1884661fda1SChao Xie unsigned int gate_flags; 1894661fda1SChao Xie spinlock_t *lock; 1904661fda1SChao Xie }; 1914661fda1SChao Xie void mmp_register_gate_clks(struct mmp_clk_unit *unit, 1924661fda1SChao Xie struct mmp_param_gate_clk *clks, 1934661fda1SChao Xie void __iomem *base, int size); 1944661fda1SChao Xie 1954661fda1SChao Xie struct mmp_param_mux_clk { 1964661fda1SChao Xie unsigned int id; 1974661fda1SChao Xie char *name; 198cb8dbfe8SLubomir Rintel const char * const *parent_name; 1994661fda1SChao Xie u8 num_parents; 2004661fda1SChao Xie unsigned long flags; 2014661fda1SChao Xie unsigned long offset; 2024661fda1SChao Xie u8 shift; 2034661fda1SChao Xie u8 width; 2044661fda1SChao Xie u8 mux_flags; 2054661fda1SChao Xie spinlock_t *lock; 2064661fda1SChao Xie }; 2074661fda1SChao Xie void mmp_register_mux_clks(struct mmp_clk_unit *unit, 2084661fda1SChao Xie struct mmp_param_mux_clk *clks, 2094661fda1SChao Xie void __iomem *base, int size); 2104661fda1SChao Xie 2114661fda1SChao Xie struct mmp_param_div_clk { 2124661fda1SChao Xie unsigned int id; 2134661fda1SChao Xie char *name; 2144661fda1SChao Xie const char *parent_name; 2154661fda1SChao Xie unsigned long flags; 2164661fda1SChao Xie unsigned long offset; 2174661fda1SChao Xie u8 shift; 2184661fda1SChao Xie u8 width; 2194661fda1SChao Xie u8 div_flags; 2204661fda1SChao Xie spinlock_t *lock; 2214661fda1SChao Xie }; 2224661fda1SChao Xie void mmp_register_div_clks(struct mmp_clk_unit *unit, 2234661fda1SChao Xie struct mmp_param_div_clk *clks, 2244661fda1SChao Xie void __iomem *base, int size); 2254661fda1SChao Xie 2265d34d0b3SLubomir Rintel struct mmp_param_pll_clk { 2275d34d0b3SLubomir Rintel unsigned int id; 2285d34d0b3SLubomir Rintel char *name; 2295d34d0b3SLubomir Rintel unsigned long default_rate; 2305d34d0b3SLubomir Rintel unsigned long enable_offset; 2315d34d0b3SLubomir Rintel u32 enable; 2325d34d0b3SLubomir Rintel unsigned long offset; 2335d34d0b3SLubomir Rintel u8 shift; 2345d34d0b3SLubomir Rintel /* MMP3 specific: */ 2355d34d0b3SLubomir Rintel unsigned long input_rate; 2365d34d0b3SLubomir Rintel unsigned long postdiv_offset; 2375d34d0b3SLubomir Rintel unsigned long postdiv_shift; 2385d34d0b3SLubomir Rintel }; 2395d34d0b3SLubomir Rintel void mmp_register_pll_clks(struct mmp_clk_unit *unit, 2405d34d0b3SLubomir Rintel struct mmp_param_pll_clk *clks, 2415d34d0b3SLubomir Rintel void __iomem *base, int size); 2425d34d0b3SLubomir Rintel 2434661fda1SChao Xie #define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \ 2444661fda1SChao Xie { \ 2454661fda1SChao Xie .width_div = (w_d), \ 2464661fda1SChao Xie .shift_div = (s_d), \ 2474661fda1SChao Xie .width_mux = (w_m), \ 2484661fda1SChao Xie .shift_mux = (s_m), \ 2494661fda1SChao Xie .bit_fc = (fc), \ 2504661fda1SChao Xie } 2514661fda1SChao Xie 2524661fda1SChao Xie void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, 2534661fda1SChao Xie int nr_clks); 2544661fda1SChao Xie void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, 2554661fda1SChao Xie struct clk *clk); 256*ee4df236SLubomir Rintel 257*ee4df236SLubomir Rintel /* Power islands */ 258*ee4df236SLubomir Rintel #define MMP_PM_DOMAIN_NO_DISABLE BIT(0) 259*ee4df236SLubomir Rintel 260*ee4df236SLubomir Rintel struct generic_pm_domain *mmp_pm_domain_register(const char *name, 261*ee4df236SLubomir Rintel void __iomem *reg, 262*ee4df236SLubomir Rintel u32 power_on, u32 reset, u32 clock_enable, 263*ee4df236SLubomir Rintel unsigned int flags, spinlock_t *lock); 264*ee4df236SLubomir Rintel 2656b63f023SChao Xie #endif 266