1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.. 4 * All rights reserved. 5 * 6 * Authors: 7 * Yifeng Huang <huangyifeng@eswincomputing.com> 8 * Xuyang Dong <dongxuyang@eswincomputing.com> 9 */ 10 11 #ifndef __ESWIN_COMMON_H__ 12 #define __ESWIN_COMMON_H__ 13 14 #define APLL_HIGH_FREQ 983040000 15 #define APLL_LOW_FREQ 225792000 16 #define PLL_HIGH_FREQ 1800000000 17 #define PLL_LOW_FREQ 24000000 18 19 /* 20 * ESWIN_PRIV_DIV_MIN_2: If ESWIN_PRIV_DIV_MIN_2 is set, the minimum value of 21 * the register is 2, i.e. the minimum division ratio is 2. 22 */ 23 #define ESWIN_PRIV_DIV_MIN_2 BIT(0) 24 25 enum eswin_clk_type { 26 CLK_FIXED_FACTOR, 27 CLK_MUX, 28 CLK_DIVIDER, 29 CLK_GATE, 30 }; 31 32 struct eswin_clock_data { 33 void __iomem *base; 34 struct clk_hw *original_clk; 35 struct notifier_block pll_nb; 36 spinlock_t lock; /* protect register read-modify-write cycle */ 37 struct clk_hw_onecell_data clk_data; 38 }; 39 40 struct eswin_divider_clock { 41 struct clk_hw hw; 42 unsigned int id; 43 const char *name; 44 const struct clk_parent_data *parent_data; 45 void __iomem *ctrl_reg; /* register address of the divider clock */ 46 unsigned long flags; 47 unsigned long reg; /* register offset */ 48 u8 shift; 49 u8 width; 50 unsigned long div_flags; 51 unsigned long priv_flag; 52 spinlock_t *lock; /* protect register read-modify-write cycle */ 53 }; 54 55 struct eswin_fixed_rate_clock { 56 struct clk_hw hw; 57 unsigned int id; 58 const char *name; 59 unsigned long flags; 60 unsigned long rate; 61 }; 62 63 struct eswin_fixed_factor_clock { 64 struct clk_hw hw; 65 unsigned int id; 66 const char *name; 67 const struct clk_parent_data *parent_data; 68 unsigned long mult; 69 unsigned long div; 70 unsigned long flags; 71 }; 72 73 struct eswin_gate_clock { 74 struct clk_hw hw; 75 unsigned int id; 76 const char *name; 77 const struct clk_parent_data *parent_data; 78 unsigned long flags; 79 unsigned long reg; 80 u8 bit_idx; 81 u8 gate_flags; 82 }; 83 84 struct eswin_mux_clock { 85 struct clk_hw hw; 86 unsigned int id; 87 const char *name; 88 const struct clk_parent_data *parent_data; 89 u8 num_parents; 90 unsigned long flags; 91 unsigned long reg; 92 u8 shift; 93 u8 width; 94 u8 mux_flags; 95 u32 *table; 96 }; 97 98 struct eswin_pll_clock { 99 struct clk_hw hw; 100 u32 id; 101 const char *name; 102 const struct clk_parent_data *parent_data; 103 const u32 ctrl_reg0; 104 const u8 fbdiv_shift; 105 106 const u32 ctrl_reg1; 107 const u8 frac_shift; 108 109 const u32 ctrl_reg2; 110 111 const u32 status_reg; 112 const u8 lock_shift; 113 const u8 lock_width; 114 115 const u64 max_rate; 116 const u64 min_rate; 117 }; 118 119 struct eswin_clk_pll { 120 struct clk_hw hw; 121 u32 id; 122 void __iomem *ctrl_reg0; 123 u8 fbdiv_shift; 124 125 void __iomem *ctrl_reg1; 126 u8 frac_shift; 127 128 void __iomem *ctrl_reg2; 129 130 void __iomem *status_reg; 131 u8 lock_shift; 132 u8 lock_width; 133 134 u64 max_rate; 135 u64 min_rate; 136 }; 137 138 struct eswin_clk_info { 139 unsigned int type; 140 unsigned int pid; 141 unsigned int id; 142 struct clk_hw hw; 143 union { 144 struct eswin_divider_clock div; 145 struct eswin_fixed_factor_clock factor; 146 struct eswin_gate_clock gate; 147 struct eswin_mux_clock mux; 148 } data; 149 }; 150 151 struct eswin_clock_data *eswin_clk_init(struct platform_device *pdev, 152 size_t nr_clks); 153 int eswin_clk_register_fixed_rate(struct device *dev, 154 struct eswin_fixed_rate_clock *clks, 155 int nums, struct eswin_clock_data *data); 156 int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks, 157 int nums, struct eswin_clock_data *data); 158 int eswin_clk_register_fixed_factor(struct device *dev, 159 struct eswin_fixed_factor_clock *clks, 160 int nums, struct eswin_clock_data *data); 161 int eswin_clk_register_mux(struct device *dev, struct eswin_mux_clock *clks, 162 int nums, struct eswin_clock_data *data); 163 int eswin_clk_register_divider(struct device *dev, 164 struct eswin_divider_clock *clks, 165 int nums, struct eswin_clock_data *data); 166 int eswin_clk_register_gate(struct device *dev, struct eswin_gate_clock *clks, 167 int nums, struct eswin_clock_data *data); 168 int eswin_clk_register_clks(struct device *dev, struct eswin_clk_info *clks, 169 int nums, struct eswin_clock_data *data); 170 struct clk_hw *eswin_register_clkdiv(struct device *dev, unsigned int id, 171 const char *name, 172 const struct clk_hw *parent_hw, 173 unsigned long flags, void __iomem *reg, 174 u8 shift, u8 width, 175 unsigned long clk_divider_flags, 176 unsigned long priv_flag, spinlock_t *lock); 177 178 #define ESWIN_DIV(_id, _name, _pdata, _flags, _reg, _shift, _width, \ 179 _dflags, _pflag) \ 180 { \ 181 .id = _id, \ 182 .name = _name, \ 183 .parent_data = _pdata, \ 184 .flags = _flags, \ 185 .reg = _reg, \ 186 .shift = _shift, \ 187 .width = _width, \ 188 .div_flags = _dflags, \ 189 .priv_flag = _pflag, \ 190 } 191 192 #define ESWIN_DIV_TYPE(_id, _name, _pid, _flags, _reg, _shift, _width, \ 193 _dflags, _pflag) \ 194 { \ 195 .type = CLK_DIVIDER, \ 196 .pid = _pid, \ 197 .id = _id, \ 198 .data = { \ 199 .div = { \ 200 .name = _name, \ 201 .flags = _flags, \ 202 .reg = _reg, \ 203 .shift = _shift, \ 204 .width = _width, \ 205 .div_flags = _dflags, \ 206 .priv_flag = _pflag, \ 207 }, \ 208 }, \ 209 } 210 211 #define ESWIN_FACTOR(_id, _name, _pdata, _mult, _div, _flags) \ 212 { \ 213 .id = _id, \ 214 .name = _name, \ 215 .parent_data = _pdata, \ 216 .mult = _mult, \ 217 .div = _div, \ 218 .flags = _flags, \ 219 } 220 221 #define ESWIN_FACTOR_TYPE(_id, _name, _pid, _mult, _div, _flags) \ 222 { \ 223 .type = CLK_FIXED_FACTOR, \ 224 .pid = _pid, \ 225 .id = _id, \ 226 .data = { \ 227 .factor = { \ 228 .name = _name, \ 229 .mult = _mult, \ 230 .div = _div, \ 231 .flags = _flags, \ 232 }, \ 233 }, \ 234 } 235 236 #define ESWIN_FIXED(_id, _name, _flags, _rate) \ 237 { \ 238 .id = _id, \ 239 .name = _name, \ 240 .flags = _flags, \ 241 .rate = _rate, \ 242 } 243 244 #define ESWIN_GATE(_id, _name, _pdata, _flags, _reg, _idx, _gflags) \ 245 { \ 246 .id = _id, \ 247 .name = _name, \ 248 .parent_data = _pdata, \ 249 .flags = _flags, \ 250 .reg = _reg, \ 251 .bit_idx = _idx, \ 252 .gate_flags = _gflags, \ 253 } 254 255 #define ESWIN_GATE_TYPE(_id, _name, _pid, _flags, _reg, _idx, _gflags) \ 256 { \ 257 .type = CLK_GATE, \ 258 .pid = _pid, \ 259 .id = _id, \ 260 .data = { \ 261 .gate = { \ 262 .name = _name, \ 263 .flags = _flags, \ 264 .reg = _reg, \ 265 .bit_idx = _idx, \ 266 .gate_flags = _gflags, \ 267 }, \ 268 }, \ 269 } 270 271 #define ESWIN_MUX(_id, _name, _pdata, _num_parents, _flags, _reg, \ 272 _shift, _width, _mflags) \ 273 { \ 274 .id = _id, \ 275 .name = _name, \ 276 .parent_data = _pdata, \ 277 .num_parents = _num_parents, \ 278 .flags = _flags, \ 279 .reg = _reg, \ 280 .shift = _shift, \ 281 .width = _width, \ 282 .mux_flags = _mflags, \ 283 .table = NULL, \ 284 } 285 286 #define ESWIN_MUX_TBL(_id, _name, _pdata, _num_parents, _flags, _reg, \ 287 _shift, _width, _mflags, _table) \ 288 { \ 289 .id = _id, \ 290 .name = _name, \ 291 .parent_data = _pdata, \ 292 .num_parents = _num_parents, \ 293 .flags = _flags, \ 294 .reg = _reg, \ 295 .shift = _shift, \ 296 .width = _width, \ 297 .mux_flags = _mflags, \ 298 .table = _table, \ 299 } 300 301 #define ESWIN_MUX_TYPE(_id, _name, _pdata, _num_parents, _flags, _reg, \ 302 _shift, _width, _mflags, _table) \ 303 { \ 304 .type = CLK_MUX, \ 305 .id = _id, \ 306 .data = { \ 307 .mux = { \ 308 .name = _name, \ 309 .parent_data = _pdata, \ 310 .num_parents = _num_parents, \ 311 .flags = _flags, \ 312 .reg = _reg, \ 313 .shift = _shift, \ 314 .width = _width, \ 315 .mux_flags = _mflags, \ 316 .table = _table, \ 317 }, \ 318 }, \ 319 } 320 321 #define ESWIN_PLL(_id, _name, _pdata, _reg0, _fb_shift, _reg1, \ 322 _frac_shift, _reg2, _reg, _lock_shift, _lock_width, \ 323 _max_rate, _min_rate) \ 324 { \ 325 .id = _id, \ 326 .name = _name, \ 327 .parent_data = _pdata, \ 328 .ctrl_reg0 = _reg0, \ 329 .fbdiv_shift = _fb_shift, \ 330 .ctrl_reg1 = _reg1, \ 331 .frac_shift = _frac_shift, \ 332 .ctrl_reg2 = _reg2, \ 333 .status_reg = _reg, \ 334 .lock_shift = _lock_shift, \ 335 .lock_width = _lock_width, \ 336 .max_rate = _max_rate, \ 337 .min_rate = _min_rate, \ 338 } 339 340 #endif /* __ESWIN_COMMON_H__ */ 341