blob: a725c1d45fb0565d3533001fc65422669e3007d4 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/* 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#include <soc/asr/asrdcstat.h>
8#include <linux/pm_qos.h>
9#include <linux/clk/dvfs-dvc.h>
10
11#define APBC_NO_BUS_CTRL BIT(0)
12#define APBC_POWER_CTRL BIT(1)
13#define APBC_FN_CTRL BIT(2)
14#define APBC_APB_CTRL BIT(3)
15#define APBC_RST_CTRL BIT(4)
16
17/* for APB pwm clock */
18#define APBC_PWM BIT(5)
19#define APBC_PWM_APB_CTRL BIT(6)
20
21/* for two bit control like TSEN in 1802s */
22#define APBC_TWO_CTRL BIT(7)
23/* for APB clock whose parent is mux */
24#define APBC_MUX BIT(8)
25
26#define MAX_OP_NUM (10)
27#define CP_REAL_DCLK_SHIFT (1)
28#define CP_REAL_DCLK_MASK (0x3FF << CP_REAL_DCLK_SHIFT)
29
30/* supported DDR chip type */
31enum ddr_type {
32 DDR_400M = 0,
33 DDR_533M,
34 DDR_416M,
35 DDR_667M,
36 DDR_800M,
37 DDR_TYPE_MAX,
38};
39
40#define KHZ (1000UL)
41#define MHZ (1000000UL)
42
43#define MHZ_TO_HZ (1000000)
44#define MHZ_TO_KHZ (1000)
45
46#define PLL_MASK(n) ((1 << (n)) - 1)
47#define MASK(n) ((1 << (n)) - 1)
48
49#define MMP_AXI_SEPERATED_SRC_SEL BIT(0)
50
51/* TODO clk-provider.h */
52#define CLK_SET_RATE_ENABLED BIT(15) /* enable clk before changing clk rate */
53
54extern enum ddr_type ddr_mode;
55extern unsigned int uisvtdro;
56extern unsigned long (*freqs_cmb)[MAX_PMIC_LEVEL];
57
58
59struct mmp_clk_factor_masks {
60 unsigned int factor;
61 unsigned int num_mask;
62 unsigned int den_mask;
63 unsigned int num_shift;
64 unsigned int den_shift;
65};
66
67struct mmp_clk_factor_tbl {
68 unsigned int num;
69 unsigned int den;
70};
71
72struct mmp_clk_factor {
73 struct clk_hw hw;
74 void __iomem *base;
75 struct mmp_clk_factor_masks *masks;
76 struct mmp_clk_factor_tbl *ftbl;
77 unsigned int ftbl_cnt;
78 spinlock_t *lock;
79};
80
81extern struct clk *mmp_clk_register_factor(const char *name,
82 const char *parent_name, unsigned long flags,
83 void __iomem *base, struct mmp_clk_factor_masks *masks,
84 struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
85 spinlock_t *lock);
86
87/* Clock type "mix" */
88#define MMP_CLK_BITS_MASK(width, shift) \
89 (((1 << (width)) - 1) << (shift))
90#define MMP_CLK_BITS_GET_VAL(data, width, shift) \
91 ((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift))
92#define MMP_CLK_BITS_SET_VAL(val, width, shift) \
93 (((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift))
94
95enum {
96 MMP_CLK_MIX_TYPE_V1,
97 MMP_CLK_MIX_TYPE_V2,
98 MMP_CLK_MIX_TYPE_V3,
99};
100
101/* The register layout */
102struct mmp_clk_mix_reg_info {
103 void __iomem *reg_clk_ctrl;
104 void __iomem *reg_clk_sel;
105 u8 width_div;
106 u8 shift_div;
107 u8 width_mux;
108 u8 shift_mux;
109 u32 bit_fc;
110};
111
112/* The suggested clock table from user. */
113struct mmp_clk_mix_clk_table {
114 unsigned long rate;
115 u8 parent_index;
116 unsigned int divisor;
117 unsigned int valid;
118};
119
120struct mmp_clk_mix_config {
121 struct mmp_clk_mix_reg_info reg_info;
122 struct mmp_clk_mix_clk_table *table;
123 unsigned int table_size;
124 u32 *mux_table;
125 struct clk_div_table *div_table;
126 u8 div_flags;
127 u8 mux_flags;
128};
129
130struct mmp_clk_mix {
131 struct clk_hw hw;
132 struct mmp_clk_mix_reg_info reg_info;
133 struct mmp_clk_mix_clk_table *table;
134 u32 *mux_table;
135 struct clk_div_table *div_table;
136 unsigned int table_size;
137 u8 div_flags;
138 u8 mux_flags;
139 unsigned int type;
140 spinlock_t *lock;
141};
142
143extern const struct clk_ops mmp_clk_mix_ops;
144extern struct clk *mmp_clk_register_mix(struct device *dev,
145 const char *name,
146 const char **parent_names,
147 u8 num_parents,
148 unsigned long flags,
149 struct mmp_clk_mix_config *config,
150 spinlock_t *lock);
151
152
153/* Clock type "gate". MMP private gate */
154#define MMP_CLK_GATE_NEED_DELAY BIT(0)
155
156struct mmp_clk_gate {
157 struct clk_hw hw;
158 void __iomem *reg;
159 u32 mask;
160 u32 val_enable;
161 u32 val_disable;
162 unsigned int flags;
163 spinlock_t *lock;
164 /* FIXME: for PWM clock, two PWMs share one APB clk */
165 struct clk *clk_share;
166};
167
168extern const struct clk_ops mmp_clk_gate_ops;
169extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
170 const char *parent_name, unsigned long flags,
171 void __iomem *reg, u32 mask, u32 val_enable,
172 u32 val_disable, unsigned int gate_flags,
173 spinlock_t *lock);
174
175
176extern struct clk *mmp_clk_register_pll2(const char *name,
177 const char *parent_name, unsigned long flags);
178extern struct clk *mmp_clk_register_apbc(const char *name,
179 const char *parent_name, void __iomem *base,
180 unsigned int delay, unsigned int apbc_flags, spinlock_t *lock);
181extern struct clk *mmp_clk_register_apmu(const char *name,
182 const char *parent_name, void __iomem *base, u32 enable_mask,
183 spinlock_t *lock);
184extern struct clk *mmp_clk_register_dvfs_dummy(const char *name,
185 const char *parent_name, unsigned long flags,
186 unsigned long init_rate);
187
188struct mmp_clk_unit {
189 unsigned int nr_clks;
190 struct clk **clk_table;
191 struct clk_onecell_data clk_data;
192};
193
194struct mmp_param_fixed_rate_clk {
195 unsigned int id;
196 char *name;
197 const char *parent_name;
198 unsigned long flags;
199 unsigned long fixed_rate;
200};
201void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
202 struct mmp_param_fixed_rate_clk *clks,
203 int size);
204
205struct mmp_param_fixed_factor_clk {
206 unsigned int id;
207 char *name;
208 const char *parent_name;
209 unsigned long mult;
210 unsigned long div;
211 unsigned long flags;
212};
213void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
214 struct mmp_param_fixed_factor_clk *clks,
215 int size);
216
217struct mmp_param_general_gate_clk {
218 unsigned int id;
219 const char *name;
220 const char *parent_name;
221 unsigned long flags;
222 unsigned long offset;
223 u8 bit_idx;
224 u8 gate_flags;
225 spinlock_t *lock;
226};
227void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
228 struct mmp_param_general_gate_clk *clks,
229 void __iomem *base, int size);
230
231struct mmp_param_gate_clk {
232 unsigned int id;
233 char *name;
234 const char *parent_name;
235 unsigned long flags;
236 unsigned long offset;
237 u32 mask;
238 u32 val_enable;
239 u32 val_disable;
240 unsigned int gate_flags;
241 spinlock_t *lock;
242};
243void mmp_register_gate_clks(struct mmp_clk_unit *unit,
244 struct mmp_param_gate_clk *clks,
245 void __iomem *base, int size);
246
247struct mmp_param_mux_clk {
248 unsigned int id;
249 char *name;
250 const char **parent_name;
251 u8 num_parents;
252 unsigned long flags;
253 unsigned long offset;
254 u8 shift;
255 u8 width;
256 u8 mux_flags;
257 spinlock_t *lock;
258};
259void mmp_register_mux_clks(struct mmp_clk_unit *unit,
260 struct mmp_param_mux_clk *clks,
261 void __iomem *base, int size);
262
263struct mmp_param_div_clk {
264 unsigned int id;
265 char *name;
266 const char *parent_name;
267 unsigned long flags;
268 unsigned long offset;
269 u8 shift;
270 u8 width;
271 u8 div_flags;
272 spinlock_t *lock;
273};
274void mmp_register_div_clks(struct mmp_clk_unit *unit,
275 struct mmp_param_div_clk *clks,
276 void __iomem *base, int size);
277
278#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \
279{ \
280 .width_div = (w_d), \
281 .shift_div = (s_d), \
282 .width_mux = (w_m), \
283 .shift_mux = (s_m), \
284 .bit_fc = (fc), \
285}
286
287struct mmp_clk_list {
288 const char *dev_id;
289 const char *con_id;
290 unsigned long initrate;
291};
292
293struct parents_table {
294 char *parent_name;
295 struct clk *parent;
296 u32 hw_sel_val;
297};
298
299struct ddr_opt {
300 unsigned int dclk; /* ddr clock */
301 unsigned int ddr_tbl_index; /* ddr FC table index */
302 unsigned int ddr_freq_level; /* ddr freq level(0~7) */
303 unsigned int ddr_volt_level; /* ddr voltage level (0~7) */
304 u32 ddr_clk_sel; /* ddr src sel val */
305 unsigned int ddr_clk_src; /* ddr src rate */
306 struct clk *ddr_parent; /* ddr clk parent node */
307 unsigned int dclk_div; /* ddr clk divider */
308};
309
310struct ddr_reg_offset {
311 /* ddr clk src sel set register */
312 u32 fcdclk_off;
313 u32 tbl_ctrl_off;
314 u32 clk_sel_shift;
315 u32 clk_sel_width;
316 u32 tbl_enable_shift;
317 u32 tbl_index_shift;
318 u32 tbl_index_width;
319};
320
321struct dfc_level_reg_offset {
322 u32 dclksel_shift;
323 u32 dclksel_width;
324 u32 ddr_clk_div_shift;
325 u32 ddr_clk_div_width;
326 u32 mc_table_num_shift;
327 u32 mc_table_num_width;
328 u32 volt_level_shift;
329 u32 volt_level_width;
330};
331
332struct dfc_ap_reg_offset {
333 u32 dfc_req_shift;
334 u32 freq_level_shift;
335 u32 freq_level_width;
336};
337
338struct ddr_params {
339 void __iomem *apmu_base;
340 void __iomem *mpmu_base;
341 void __iomem *dmcu_base;
342 struct ddr_reg_offset *ddr_offset;
343 struct dfc_level_reg_offset *dfc_level_reg_offset;
344 struct dfc_ap_reg_offset *dfc_ap_reg_offset;
345 struct parents_table *parent_table;
346 int parent_table_size;
347 struct ddr_opt *ddr_opt;
348 int ddr_opt_size;
349 unsigned long *hwdfc_freq_table;
350 int hwdfc_table_size;
351 /* dynamic dc stat support? */
352 bool dcstat_support;
353};
354
355struct clk_ddr {
356 struct clk_hw hw;
357 struct ddr_params *params;
358 u32 flags;
359 spinlock_t *lock;
360};
361
362struct ddr_combclk_relation {
363 unsigned long dclk_rate;
364 unsigned long combclk_rate;
365};
366
367struct ddr_combined_clk {
368 struct clk *clk;
369 unsigned long maxrate;
370 struct list_head node;
371 /* Describe the relationship with Dclk */
372 struct ddr_combclk_relation *relationtbl;
373 unsigned int num_relationtbl;
374};
375
376/* FLAGS */
377/* indicate if hwdfc or sw lagency dfc is used */
378#define MMP_DDR_HWDFC_FEAT BIT(0)
379#define MMP_DDR_FC_HARDWARE_ENABLE BIT(1)
380#define MMP_DDR_HAS_HW_VBLANK_DFC BIT(2)
381/* used for hwdfc WR, add more flag in case need to separate
382 diff issue on diff plat */
383#define MMP_DDR_HWDFC_WR BIT(3)
384#define MMP_DDR_PLLSEL_3BIT BIT(4)
385#define MMP_DDR_DLL_BYPASS BIT(5)
386/* only show ddr rate for AP part */
387#define MMP_DDR_RATE_AP_ONLY BIT(6)
388#define MMP_DDR_FC_BY_CP BIT(7)
389#define MMP_DDR_RIPC_LOCK_FC BIT(8)
390
391/* RTC/WTC table used for solution change rtc/wtc on the fly */
392struct cpu_rtcwtc {
393 unsigned int max_pclk; /* max rate could be used by this rtc/wtc */
394 unsigned int l1_rtc;
395 unsigned int l2_rtc;
396 unsigned int svtdro;
397};
398
399struct cpu_opt {
400 unsigned int pclk; /* core clock */
401 unsigned int l2clk; /* L2 cache interface clock */
402 unsigned int pdclk; /* DDR interface clock */
403 unsigned int baclk; /* bus interface clock */
404 unsigned int periphclk; /* PERIPHCLK */
405 unsigned int ap_clk_sel; /* core src sel val */
406 struct clk *parent; /* core clk parent node */
407 unsigned int ap_clk_src; /* core src rate */
408 unsigned int pclk_div; /* core clk divider*/
409 unsigned int l2clk_div; /* L2 clock divider */
410 unsigned int pdclk_div; /* DDR interface clock divider */
411 unsigned int baclk_div; /* bus interface clock divider */
412 unsigned int periphclk_div; /* PERIPHCLK divider */
413 unsigned int l1_rtc; /* L1 cache RTC/WTC */
414 unsigned int l2_rtc; /* L2 cache RTC/WTC */
415 struct list_head node;
416};
417
418struct core_reg_offset {
419 /* core clk src sel set register */
420 u32 fcap_off;
421 u32 clk_sel_shift;
422 u32 clk_sel_width;
423 void __iomem *pll1_pll3_swreg;
424 u32 pll1_pll3_swbit;
425};
426
427struct core_params {
428 void __iomem *apmu_base;
429 void __iomem *mpmu_base;
430 void __iomem *ciu_base;
431 struct core_reg_offset *core_offset;
432 struct parents_table *parent_table;
433 int parent_table_size;
434 struct cpu_opt *cpu_opt;
435 int cpu_opt_size;
436#ifdef UPDATE_CPUDFC_XTC
437 struct cpu_rtcwtc *cpu_rtcwtc_table;
438 int cpu_rtcwtc_table_size;
439#endif
440 unsigned int max_cpurate;
441 unsigned int bridge_cpurate;
442 unsigned int *pp_disable;
443 unsigned int pp_discnt;
444 /* dynamic dc stat support? */
445 bool dcstat_support;
446 powermode pxa_powermode;
447 spinlock_t *shared_lock;
448};
449
450struct axi_opt {
451 unsigned int aclk; /* axi clock */
452 u32 axi_clk_sel; /* axi src sel val */
453 unsigned int axi_clk_src; /* axi src rate */
454 struct clk *axi_parent; /* axi clk parent node */
455 unsigned int aclk_div; /* axi clk divider */
456 u32 combined_apb_clk;
457 u32 combined_apb_clk_sel;
458};
459
460struct axi_reg_offset {
461 /* axi clk src sel set register */
462 u32 fcaclk_off;
463 u32 clk_sel0_shift;
464 u32 clk_sel0_width;
465 u32 clk_sel1_shift;
466 u32 clk_sel1_width;
467};
468
469struct axi_params {
470 void __iomem *apmu_base;
471 void __iomem *mpmu_base;
472 void __iomem *apbs_base;
473 struct axi_reg_offset *axi_offset;
474 struct parents_table *parent_table;
475 int parent_table_size;
476 struct axi_opt *axi_opt;
477 int axi_opt_size;
478 /* dynamic dc stat support? */
479 bool dcstat_support;
480};
481
482struct clk_cpu {
483 struct clk_hw hw;
484 struct core_params *params;
485 u32 flags;
486 spinlock_t *lock;
487};
488
489struct clk_axi {
490 struct clk_hw hw;
491 struct axi_params *params;
492 u32 flags;
493 spinlock_t *lock;
494};
495
496#define to_clk_cpu(core) container_of(core, struct clk_cpu, hw)
497#define to_clk_axi(axi) container_of(axi, struct clk_axi, hw)
498#define to_clk_ddr(ddr) container_of(ddr, struct clk_ddr, hw)
499
500void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
501 int nr_clks);
502void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
503 struct clk *clk);
504extern int get_voltage_table_for_cp(unsigned int *dvc_voltage_tbl, unsigned int *level_num);
505extern int ddr_get_dvc_level(int rate);
506extern int __init setup_asr18xx_dvfs_platinfo(void);
507extern int __init setup_asr1901_dvfs_platinfo(void);
508#endif