1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | // |
3 | // Spreadtrum pll clock driver |
4 | // |
5 | // Copyright (C) 2015~2017 Spreadtrum, Inc. |
6 | // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> |
7 | |
8 | #ifndef _SPRD_PLL_H_ |
9 | #define _SPRD_PLL_H_ |
10 | |
11 | #include "common.h" |
12 | |
13 | struct reg_cfg { |
14 | u32 val; |
15 | u32 msk; |
16 | }; |
17 | |
18 | struct clk_bit_field { |
19 | u8 shift; |
20 | u8 width; |
21 | }; |
22 | |
23 | enum { |
24 | PLL_LOCK_DONE, |
25 | PLL_DIV_S, |
26 | PLL_MOD_EN, |
27 | PLL_SDM_EN, |
28 | PLL_REFIN, |
29 | PLL_IBIAS, |
30 | PLL_N, |
31 | PLL_NINT, |
32 | PLL_KINT, |
33 | PLL_PREDIV, |
34 | PLL_POSTDIV, |
35 | |
36 | PLL_FACT_MAX |
37 | }; |
38 | |
39 | /* |
40 | * struct sprd_pll - definition of adjustable pll clock |
41 | * |
42 | * @reg: registers used to set the configuration of pll clock, |
43 | * reg[0] shows how many registers this pll clock uses. |
44 | * @itable: pll ibias table, itable[0] means how many items this |
45 | * table includes |
46 | * @udelay delay time after setting rate |
47 | * @factors used to calculate the pll clock rate |
48 | * @fvco: fvco threshold rate |
49 | * @fflag: fvco flag |
50 | */ |
51 | struct sprd_pll { |
52 | u32 regs_num; |
53 | const u64 *itable; |
54 | const struct clk_bit_field *factors; |
55 | u16 udelay; |
56 | u16 k1; |
57 | u16 k2; |
58 | u16 fflag; |
59 | u64 fvco; |
60 | |
61 | struct sprd_clk_common common; |
62 | }; |
63 | |
64 | #define SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, \ |
65 | _regs_num, _itable, _factors, \ |
66 | _udelay, _k1, _k2, _fflag, \ |
67 | _fvco, _fn) \ |
68 | struct sprd_pll _struct = { \ |
69 | .regs_num = _regs_num, \ |
70 | .itable = _itable, \ |
71 | .factors = _factors, \ |
72 | .udelay = _udelay, \ |
73 | .k1 = _k1, \ |
74 | .k2 = _k2, \ |
75 | .fflag = _fflag, \ |
76 | .fvco = _fvco, \ |
77 | .common = { \ |
78 | .regmap = NULL, \ |
79 | .reg = _reg, \ |
80 | .hw.init = _fn(_name, _parent, \ |
81 | &sprd_pll_ops, 0),\ |
82 | }, \ |
83 | } |
84 | |
85 | #define SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ |
86 | _regs_num, _itable, _factors, \ |
87 | _udelay, _k1, _k2, _fflag, _fvco) \ |
88 | SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ |
89 | _itable, _factors, _udelay, _k1, _k2, \ |
90 | _fflag, _fvco, CLK_HW_INIT) |
91 | |
92 | #define SPRD_PLL_WITH_ITABLE_K(_struct, _name, _parent, _reg, \ |
93 | _regs_num, _itable, _factors, \ |
94 | _udelay, _k1, _k2) \ |
95 | SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ |
96 | _regs_num, _itable, _factors, \ |
97 | _udelay, _k1, _k2, 0, 0) |
98 | |
99 | #define SPRD_PLL_WITH_ITABLE_1K(_struct, _name, _parent, _reg, \ |
100 | _regs_num, _itable, _factors, _udelay) \ |
101 | SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ |
102 | _regs_num, _itable, _factors, \ |
103 | _udelay, 1000, 1000, 0, 0) |
104 | |
105 | #define SPRD_PLL_FW_NAME(_struct, _name, _parent, _reg, _regs_num, \ |
106 | _itable, _factors, _udelay, _k1, _k2, \ |
107 | _fflag, _fvco) \ |
108 | SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ |
109 | _itable, _factors, _udelay, _k1, _k2, \ |
110 | _fflag, _fvco, CLK_HW_INIT_FW_NAME) |
111 | |
112 | #define SPRD_PLL_HW(_struct, _name, _parent, _reg, _regs_num, _itable, \ |
113 | _factors, _udelay, _k1, _k2, _fflag, _fvco) \ |
114 | SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ |
115 | _itable, _factors, _udelay, _k1, _k2, \ |
116 | _fflag, _fvco, CLK_HW_INIT_HW) |
117 | |
118 | static inline struct sprd_pll *hw_to_sprd_pll(struct clk_hw *hw) |
119 | { |
120 | struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); |
121 | |
122 | return container_of(common, struct sprd_pll, common); |
123 | } |
124 | |
125 | extern const struct clk_ops sprd_pll_ops; |
126 | |
127 | #endif /* _SPRD_PLL_H_ */ |
128 | |