1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (c) 2016 Maxime Ripard. All rights reserved. |
4 | */ |
5 | |
6 | #ifndef _CCU_NM_H_ |
7 | #define _CCU_NM_H_ |
8 | |
9 | #include <linux/clk-provider.h> |
10 | |
11 | #include "ccu_common.h" |
12 | #include "ccu_div.h" |
13 | #include "ccu_frac.h" |
14 | #include "ccu_mult.h" |
15 | #include "ccu_sdm.h" |
16 | |
17 | /* |
18 | * struct ccu_nm - Definition of an N-M clock |
19 | * |
20 | * Clocks based on the formula parent * N / M |
21 | */ |
22 | struct ccu_nm { |
23 | u32 enable; |
24 | u32 lock; |
25 | |
26 | struct ccu_mult_internal n; |
27 | struct ccu_div_internal m; |
28 | struct ccu_frac_internal frac; |
29 | struct ccu_sdm_internal sdm; |
30 | |
31 | unsigned int fixed_post_div; |
32 | unsigned int min_rate; |
33 | unsigned int max_rate; |
34 | |
35 | struct ccu_common common; |
36 | }; |
37 | |
38 | #define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg, \ |
39 | _nshift, _nwidth, \ |
40 | _mshift, _mwidth, \ |
41 | _sdm_table, _sdm_en, \ |
42 | _sdm_reg, _sdm_reg_en, \ |
43 | _gate, _lock, _flags) \ |
44 | struct ccu_nm _struct = { \ |
45 | .enable = _gate, \ |
46 | .lock = _lock, \ |
47 | .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ |
48 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
49 | .sdm = _SUNXI_CCU_SDM(_sdm_table, _sdm_en, \ |
50 | _sdm_reg, _sdm_reg_en),\ |
51 | .common = { \ |
52 | .reg = _reg, \ |
53 | .features = CCU_FEATURE_SIGMA_DELTA_MOD, \ |
54 | .hw.init = CLK_HW_INIT(_name, \ |
55 | _parent, \ |
56 | &ccu_nm_ops, \ |
57 | _flags), \ |
58 | }, \ |
59 | } |
60 | |
61 | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg, \ |
62 | _nshift, _nwidth, \ |
63 | _mshift, _mwidth, \ |
64 | _frac_en, _frac_sel, \ |
65 | _frac_rate_0, _frac_rate_1, \ |
66 | _gate, _lock, _flags) \ |
67 | struct ccu_nm _struct = { \ |
68 | .enable = _gate, \ |
69 | .lock = _lock, \ |
70 | .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ |
71 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
72 | .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ |
73 | _frac_rate_0, \ |
74 | _frac_rate_1), \ |
75 | .common = { \ |
76 | .reg = _reg, \ |
77 | .features = CCU_FEATURE_FRACTIONAL, \ |
78 | .hw.init = CLK_HW_INIT(_name, \ |
79 | _parent, \ |
80 | &ccu_nm_ops, \ |
81 | _flags), \ |
82 | }, \ |
83 | } |
84 | |
85 | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(_struct, _name, _parent, \ |
86 | _reg, _min_rate, \ |
87 | _nshift, _nwidth, \ |
88 | _mshift, _mwidth, \ |
89 | _frac_en, _frac_sel, \ |
90 | _frac_rate_0, _frac_rate_1,\ |
91 | _gate, _lock, _flags) \ |
92 | struct ccu_nm _struct = { \ |
93 | .enable = _gate, \ |
94 | .lock = _lock, \ |
95 | .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ |
96 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
97 | .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ |
98 | _frac_rate_0, \ |
99 | _frac_rate_1), \ |
100 | .min_rate = _min_rate, \ |
101 | .common = { \ |
102 | .reg = _reg, \ |
103 | .features = CCU_FEATURE_FRACTIONAL, \ |
104 | .hw.init = CLK_HW_INIT(_name, \ |
105 | _parent, \ |
106 | &ccu_nm_ops, \ |
107 | _flags), \ |
108 | }, \ |
109 | } |
110 | |
111 | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \ |
112 | _parent, _reg, \ |
113 | _min_rate, _max_rate, \ |
114 | _nshift, _nwidth, \ |
115 | _mshift, _mwidth, \ |
116 | _frac_en, _frac_sel, \ |
117 | _frac_rate_0, \ |
118 | _frac_rate_1, \ |
119 | _gate, _lock, _flags, \ |
120 | _features) \ |
121 | struct ccu_nm _struct = { \ |
122 | .enable = _gate, \ |
123 | .lock = _lock, \ |
124 | .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ |
125 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
126 | .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ |
127 | _frac_rate_0, \ |
128 | _frac_rate_1), \ |
129 | .min_rate = _min_rate, \ |
130 | .max_rate = _max_rate, \ |
131 | .common = { \ |
132 | .reg = _reg, \ |
133 | .features = _features, \ |
134 | .hw.init = CLK_HW_INIT(_name, \ |
135 | _parent, \ |
136 | &ccu_nm_ops, \ |
137 | _flags), \ |
138 | }, \ |
139 | } |
140 | |
141 | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \ |
142 | _parent, _reg, \ |
143 | _min_rate, _max_rate, \ |
144 | _nshift, _nwidth, \ |
145 | _mshift, _mwidth, \ |
146 | _frac_en, _frac_sel, \ |
147 | _frac_rate_0, \ |
148 | _frac_rate_1, \ |
149 | _gate, _lock, _flags) \ |
150 | SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \ |
151 | _parent, _reg, \ |
152 | _min_rate, _max_rate, \ |
153 | _nshift, _nwidth, \ |
154 | _mshift, _mwidth, \ |
155 | _frac_en, _frac_sel, \ |
156 | _frac_rate_0, \ |
157 | _frac_rate_1, \ |
158 | _gate, _lock, _flags, \ |
159 | CCU_FEATURE_FRACTIONAL) |
160 | |
161 | #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(_struct, _name, \ |
162 | _parent, _reg, \ |
163 | _min_rate, _max_rate, \ |
164 | _nshift, _nwidth, \ |
165 | _mshift, _mwidth, \ |
166 | _frac_en, _frac_sel, \ |
167 | _frac_rate_0, \ |
168 | _frac_rate_1, \ |
169 | _gate, _lock, _flags) \ |
170 | SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_FEAT(_struct, _name, \ |
171 | _parent, _reg, \ |
172 | _min_rate, _max_rate, \ |
173 | _nshift, _nwidth, \ |
174 | _mshift, _mwidth, \ |
175 | _frac_en, _frac_sel, \ |
176 | _frac_rate_0, \ |
177 | _frac_rate_1, \ |
178 | _gate, _lock, _flags, \ |
179 | CCU_FEATURE_FRACTIONAL |\ |
180 | CCU_FEATURE_CLOSEST_RATE) |
181 | |
182 | #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ |
183 | _nshift, _nwidth, \ |
184 | _mshift, _mwidth, \ |
185 | _gate, _lock, _flags) \ |
186 | struct ccu_nm _struct = { \ |
187 | .enable = _gate, \ |
188 | .lock = _lock, \ |
189 | .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ |
190 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
191 | .common = { \ |
192 | .reg = _reg, \ |
193 | .hw.init = CLK_HW_INIT(_name, \ |
194 | _parent, \ |
195 | &ccu_nm_ops, \ |
196 | _flags), \ |
197 | }, \ |
198 | } |
199 | |
200 | static inline struct ccu_nm *hw_to_ccu_nm(struct clk_hw *hw) |
201 | { |
202 | struct ccu_common *common = hw_to_ccu_common(hw); |
203 | |
204 | return container_of(common, struct ccu_nm, common); |
205 | } |
206 | |
207 | extern const struct clk_ops ccu_nm_ops; |
208 | |
209 | #endif /* _CCU_NM_H_ */ |
210 | |