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