1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __MACH_MMP_CLK_H 3 #define __MACH_MMP_CLK_H 4 5 #include <linux/clk-provider.h> 6 #include <linux/pm_domain.h> 7 #include <linux/clkdev.h> 8 9 #define APBC_NO_BUS_CTRL BIT(0) 10 #define APBC_POWER_CTRL BIT(1) 11 12 13 /* Clock type "factor" */ 14 struct mmp_clk_factor_masks { 15 unsigned int factor; 16 unsigned int num_mask; 17 unsigned int den_mask; 18 unsigned int num_shift; 19 unsigned int den_shift; 20 unsigned int enable_mask; 21 }; 22 23 struct mmp_clk_factor_tbl { 24 unsigned int num; 25 unsigned int den; 26 }; 27 28 struct mmp_clk_factor { 29 struct clk_hw hw; 30 void __iomem *base; 31 struct mmp_clk_factor_masks *masks; 32 struct mmp_clk_factor_tbl *ftbl; 33 unsigned int ftbl_cnt; 34 spinlock_t *lock; 35 }; 36 37 extern struct clk *mmp_clk_register_factor(const char *name, 38 const char *parent_name, unsigned long flags, 39 void __iomem *base, struct mmp_clk_factor_masks *masks, 40 struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt, 41 spinlock_t *lock); 42 43 /* Clock type "mix" */ 44 #define MMP_CLK_BITS_MASK(width, shift) \ 45 (((1 << (width)) - 1) << (shift)) 46 #define MMP_CLK_BITS_GET_VAL(data, width, shift) \ 47 ((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift)) 48 #define MMP_CLK_BITS_SET_VAL(val, width, shift) \ 49 (((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift)) 50 51 enum { 52 MMP_CLK_MIX_TYPE_V1, 53 MMP_CLK_MIX_TYPE_V2, 54 MMP_CLK_MIX_TYPE_V3, 55 }; 56 57 /* The register layout */ 58 struct mmp_clk_mix_reg_info { 59 void __iomem *reg_clk_ctrl; 60 void __iomem *reg_clk_sel; 61 u8 width_div; 62 u8 shift_div; 63 u8 width_mux; 64 u8 shift_mux; 65 u8 bit_fc; 66 }; 67 68 /* The suggested clock table from user. */ 69 struct mmp_clk_mix_clk_table { 70 unsigned long rate; 71 u8 parent_index; 72 unsigned int divisor; 73 unsigned int valid; 74 }; 75 76 struct mmp_clk_mix_config { 77 struct mmp_clk_mix_reg_info reg_info; 78 struct mmp_clk_mix_clk_table *table; 79 unsigned int table_size; 80 u32 *mux_table; 81 struct clk_div_table *div_table; 82 u8 div_flags; 83 u8 mux_flags; 84 }; 85 86 struct mmp_clk_mix { 87 struct clk_hw hw; 88 struct mmp_clk_mix_reg_info reg_info; 89 struct mmp_clk_mix_clk_table *table; 90 u32 *mux_table; 91 struct clk_div_table *div_table; 92 unsigned int table_size; 93 u8 div_flags; 94 u8 mux_flags; 95 unsigned int type; 96 spinlock_t *lock; 97 }; 98 99 extern const struct clk_ops mmp_clk_mix_ops; 100 extern struct clk *mmp_clk_register_mix(struct device *dev, 101 const char *name, 102 const char * const *parent_names, 103 u8 num_parents, 104 unsigned long flags, 105 struct mmp_clk_mix_config *config, 106 spinlock_t *lock); 107 108 109 /* Clock type "gate". MMP private gate */ 110 #define MMP_CLK_GATE_NEED_DELAY BIT(0) 111 112 struct mmp_clk_gate { 113 struct clk_hw hw; 114 void __iomem *reg; 115 u32 mask; 116 u32 val_enable; 117 u32 val_disable; 118 unsigned int flags; 119 spinlock_t *lock; 120 }; 121 122 extern const struct clk_ops mmp_clk_gate_ops; 123 extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name, 124 const char *parent_name, unsigned long flags, 125 void __iomem *reg, u32 mask, u32 val_enable, 126 u32 val_disable, unsigned int gate_flags, 127 spinlock_t *lock); 128 129 extern struct clk *mmp_clk_register_apbc(const char *name, 130 const char *parent_name, void __iomem *base, 131 unsigned int delay, unsigned int apbc_flags, spinlock_t *lock); 132 extern struct clk *mmp_clk_register_apmu(const char *name, 133 const char *parent_name, void __iomem *base, u32 enable_mask, 134 spinlock_t *lock); 135 136 struct mmp_clk_unit { 137 unsigned int nr_clks; 138 struct clk **clk_table; 139 struct clk_onecell_data clk_data; 140 }; 141 142 struct mmp_param_fixed_rate_clk { 143 unsigned int id; 144 char *name; 145 const char *parent_name; 146 unsigned long flags; 147 unsigned long fixed_rate; 148 }; 149 void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit, 150 struct mmp_param_fixed_rate_clk *clks, 151 int size); 152 153 struct mmp_param_fixed_factor_clk { 154 unsigned int id; 155 char *name; 156 const char *parent_name; 157 unsigned long mult; 158 unsigned long div; 159 unsigned long flags; 160 }; 161 void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit, 162 struct mmp_param_fixed_factor_clk *clks, 163 int size); 164 165 struct mmp_param_general_gate_clk { 166 unsigned int id; 167 const char *name; 168 const char *parent_name; 169 unsigned long flags; 170 unsigned long offset; 171 u8 bit_idx; 172 u8 gate_flags; 173 spinlock_t *lock; 174 }; 175 void mmp_register_general_gate_clks(struct mmp_clk_unit *unit, 176 struct mmp_param_general_gate_clk *clks, 177 void __iomem *base, int size); 178 179 struct mmp_param_gate_clk { 180 unsigned int id; 181 char *name; 182 const char *parent_name; 183 unsigned long flags; 184 unsigned long offset; 185 u32 mask; 186 u32 val_enable; 187 u32 val_disable; 188 unsigned int gate_flags; 189 spinlock_t *lock; 190 }; 191 void mmp_register_gate_clks(struct mmp_clk_unit *unit, 192 struct mmp_param_gate_clk *clks, 193 void __iomem *base, int size); 194 195 struct mmp_param_mux_clk { 196 unsigned int id; 197 char *name; 198 const char * const *parent_name; 199 u8 num_parents; 200 unsigned long flags; 201 unsigned long offset; 202 u8 shift; 203 u8 width; 204 u8 mux_flags; 205 spinlock_t *lock; 206 }; 207 void mmp_register_mux_clks(struct mmp_clk_unit *unit, 208 struct mmp_param_mux_clk *clks, 209 void __iomem *base, int size); 210 211 struct mmp_param_div_clk { 212 unsigned int id; 213 char *name; 214 const char *parent_name; 215 unsigned long flags; 216 unsigned long offset; 217 u8 shift; 218 u8 width; 219 u8 div_flags; 220 spinlock_t *lock; 221 }; 222 void mmp_register_div_clks(struct mmp_clk_unit *unit, 223 struct mmp_param_div_clk *clks, 224 void __iomem *base, int size); 225 226 struct mmp_param_pll_clk { 227 unsigned int id; 228 char *name; 229 unsigned long default_rate; 230 unsigned long enable_offset; 231 u32 enable; 232 unsigned long offset; 233 u8 shift; 234 /* MMP3 specific: */ 235 unsigned long input_rate; 236 unsigned long postdiv_offset; 237 unsigned long postdiv_shift; 238 }; 239 void mmp_register_pll_clks(struct mmp_clk_unit *unit, 240 struct mmp_param_pll_clk *clks, 241 void __iomem *base, int size); 242 243 #define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \ 244 { \ 245 .width_div = (w_d), \ 246 .shift_div = (s_d), \ 247 .width_mux = (w_m), \ 248 .shift_mux = (s_m), \ 249 .bit_fc = (fc), \ 250 } 251 252 void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, 253 int nr_clks); 254 void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, 255 struct clk *clk); 256 257 /* Power islands */ 258 #define MMP_PM_DOMAIN_NO_DISABLE BIT(0) 259 260 struct generic_pm_domain *mmp_pm_domain_register(const char *name, 261 void __iomem *reg, 262 u32 power_on, u32 reset, u32 clock_enable, 263 unsigned int flags, spinlock_t *lock); 264 265 #endif 266