xref: /OK3568_Linux_fs/kernel/drivers/clk/rockchip/regmap/clk-regmap.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14 
15 #ifndef __CLK_REGMAP_H__
16 #define __CLK_REGMAP_H__
17 
18 #include <linux/regmap.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/clk-provider.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 
26 #define UPDATE(x, h, l)		(((x) << (l)) & GENMASK((h), (l)))
27 #define HIWORD_UPDATE(v, h, l)	(((v) << (l)) | (GENMASK((h), (l)) << 16))
28 
29 struct clk_pll_data {
30 	unsigned int id;
31 	const char *name;
32 	const char *parent_name;
33 	u32 reg;
34 	u8 pd_shift;
35 	u8 dsmpd_shift;
36 	u8 lock_shift;
37 	unsigned long flags;
38 };
39 
40 #define PLL(_id, _name, _parent_name, _reg, _pd_shift, _dsmpd_shift, \
41 	    _lock_shift, _flags) \
42 { \
43 	.id = _id, \
44 	.name = _name, \
45 	.parent_name = _parent_name, \
46 	.reg = _reg, \
47 	.pd_shift = _pd_shift, \
48 	.dsmpd_shift = _dsmpd_shift, \
49 	.lock_shift = _lock_shift, \
50 	.flags = _flags, \
51 }
52 
53 #define RK618_PLL(_id, _name, _parent_name, _reg, _flags) \
54 	PLL(_id, _name, _parent_name, _reg, 10, 9, 15, _flags)
55 
56 struct clk_mux_data {
57 	unsigned int id;
58 	const char *name;
59 	const char *const *parent_names;
60 	u8 num_parents;
61 	u32 reg;
62 	u8 shift;
63 	u8 width;
64 	unsigned long flags;
65 };
66 
67 #define MUX(_id, _name, _parent_names, _reg, _shift, _width, _flags) \
68 { \
69 	.id = _id, \
70 	.name = _name, \
71 	.parent_names = _parent_names, \
72 	.num_parents = ARRAY_SIZE(_parent_names), \
73 	.reg = _reg, \
74 	.shift = _shift, \
75 	.width = _width, \
76 	.flags = _flags, \
77 }
78 
79 struct clk_gate_data {
80 	unsigned int id;
81 	const char *name;
82 	const char *parent_name;
83 	u32 reg;
84 	u8 shift;
85 	unsigned long flags;
86 };
87 
88 #define GATE(_id, _name, _parent_name, _reg, _shift, _flags) \
89 { \
90 	.id = _id, \
91 	.name = _name, \
92 	.parent_name = _parent_name, \
93 	.reg = _reg, \
94 	.shift = _shift, \
95 	.flags = _flags, \
96 }
97 
98 struct clk_divider_data {
99 	unsigned int id;
100 	const char *name;
101 	const char *parent_name;
102 	u32 reg;
103 	u8 shift;
104 	u8 width;
105 	unsigned long flags;
106 };
107 
108 #define DIV(_id, _name, _parent_name, _reg, _shift, _width, _flags) \
109 { \
110 	.id = _id, \
111 	.name = _name, \
112 	.parent_name = _parent_name, \
113 	.reg = _reg, \
114 	.shift = _shift, \
115 	.width = _width, \
116 	.flags = _flags, \
117 }
118 
119 struct clk_composite_data {
120 	unsigned int id;
121 	const char *name;
122 	const char *const *parent_names;
123 	u8 num_parents;
124 	u32 mux_reg;
125 	u8 mux_shift;
126 	u8 mux_width;
127 	u32 div_reg;
128 	u8 div_shift;
129 	u8 div_width;
130 	u8 div_flags;
131 	u32 gate_reg;
132 	u8 gate_shift;
133 	unsigned long flags;
134 };
135 
136 #define COMPOSITE(_id, _name, _parent_names, \
137 		  _mux_reg, _mux_shift, _mux_width, \
138 		  _div_reg, _div_shift, _div_width, \
139 		  _gate_reg, _gate_shift, _flags) \
140 { \
141 	.id = _id, \
142 	.name = _name, \
143 	.parent_names = _parent_names, \
144 	.num_parents = ARRAY_SIZE(_parent_names), \
145 	.mux_reg = _mux_reg, \
146 	.mux_shift = _mux_shift, \
147 	.mux_width = _mux_width, \
148 	.div_reg = _div_reg, \
149 	.div_shift = _div_shift, \
150 	.div_width = _div_width, \
151 	.div_flags = CLK_DIVIDER_HIWORD_MASK, \
152 	.gate_reg = _gate_reg, \
153 	.gate_shift = _gate_shift, \
154 	.flags = _flags, \
155 }
156 
157 #define COMPOSITE_NOMUX(_id, _name, _parent_name, \
158 			_div_reg, _div_shift, _div_width, \
159 			_gate_reg, _gate_shift, _flags) \
160 { \
161 	.id = _id, \
162 	.name = _name, \
163 	.parent_names = (const char *[]){ _parent_name }, \
164 	.num_parents = 1, \
165 	.div_reg = _div_reg, \
166 	.div_shift = _div_shift, \
167 	.div_width = _div_width, \
168 	.div_flags = CLK_DIVIDER_HIWORD_MASK, \
169 	.gate_reg = _gate_reg, \
170 	.gate_shift = _gate_shift, \
171 	.flags = _flags, \
172 }
173 
174 #define COMPOSITE_NODIV(_id, _name, _parent_names, \
175 			_mux_reg, _mux_shift, _mux_width, \
176 			_gate_reg, _gate_shift, _flags) \
177 	COMPOSITE(_id, _name, _parent_names, \
178 		 _mux_reg, _mux_shift, _mux_width, \
179 		 0, 0, 0, \
180 		 _gate_reg, _gate_shift, _flags)
181 
182 #define COMPOSITE_FRAC(_id, _name, _parent_names, \
183 		       _mux_reg, _mux_shift, _mux_width, \
184 		       _div_reg, \
185 		       _gate_reg, _gate_shift, _flags) \
186 { \
187 	.id = _id, \
188 	.name = _name, \
189 	.parent_names = _parent_names, \
190 	.num_parents = ARRAY_SIZE(_parent_names), \
191 	.mux_reg = _mux_reg, \
192 	.mux_shift = _mux_shift, \
193 	.mux_width = _mux_width, \
194 	.div_reg = _div_reg, \
195 	.gate_reg = _gate_reg, \
196 	.gate_shift = _gate_shift, \
197 	.flags = _flags, \
198 }
199 
200 #define COMPOSITE_FRAC_NOMUX(_id, _name, _parent_name, \
201 			     _div_reg, \
202 			     _gate_reg, _gate_shift, _flags) \
203 { \
204 	.id = _id, \
205 	.name = _name, \
206 	.parent_names = (const char *[]){ _parent_name }, \
207 	.num_parents = 1, \
208 	.div_reg = _div_reg, \
209 	.gate_reg = _gate_reg, \
210 	.gate_shift = _gate_shift, \
211 	.flags = _flags, \
212 }
213 
214 #define COMPOSITE_FRAC_NOGATE(_id, _name, _parent_names, \
215 			      _mux_reg, _mux_shift, _mux_width, \
216 			      _div_reg, \
217 			      _flags) \
218 	COMPOSITE_FRAC(_id, _name, _parent_names, \
219 		       _mux_reg, _mux_shift, _mux_width, \
220 			_div_reg, 0, 0, _flags)
221 
222 struct clk_regmap_fractional_divider {
223 	struct clk_hw hw;
224 	struct device *dev;
225 	struct regmap *regmap;
226 	u32 reg;
227 	u8 mshift;
228 	u8 mwidth;
229 	u32 mmask;
230 	u8 nshift;
231 	u8 nwidth;
232 	u32 nmask;
233 };
234 
235 struct clk_regmap_divider {
236 	struct clk_hw hw;
237 	struct device *dev;
238 	struct regmap *regmap;
239 	u32 reg;
240 	u8 shift;
241 	u8 width;
242 };
243 
244 struct clk_regmap_gate {
245 	struct clk_hw hw;
246 	struct device *dev;
247 	struct regmap *regmap;
248 	u32 reg;
249 	u8 shift;
250 };
251 
252 struct clk_regmap_mux {
253 	struct clk_hw hw;
254 	struct device *dev;
255 	struct regmap *regmap;
256 	u32 reg;
257 	u32 mask;
258 	u8 shift;
259 };
260 
261 extern const struct clk_ops clk_regmap_mux_ops;
262 extern const struct clk_ops clk_regmap_divider_ops;
263 extern const struct clk_ops clk_regmap_gate_ops;
264 extern const struct clk_ops clk_regmap_fractional_divider_ops;
265 
266 struct clk *
267 devm_clk_regmap_register_pll(struct device *dev, const char *name,
268 			     const char *parent_name,
269 			     struct regmap *regmap, u32 reg, u8 pd_shift,
270 			     u8 dsmpd_shift, u8 lock_shift,
271 			     unsigned long flags);
272 
273 struct clk *
274 devm_clk_regmap_register_mux(struct device *dev, const char *name,
275 			     const char * const *parent_names, u8 num_parents,
276 			     struct regmap *regmap, u32 reg, u8 shift, u8 width,
277 			     unsigned long flags);
278 
279 struct clk *
280 devm_clk_regmap_register_divider(struct device *dev, const char *name,
281 				 const char *parent_name, struct regmap *regmap,
282 				 u32 reg, u8 shift, u8 width,
283 				 unsigned long flags);
284 
285 struct clk *
286 devm_clk_regmap_register_gate(struct device *dev, const char *name,
287 			      const char *parent_name,
288 			      struct regmap *regmap, u32 reg, u8 shift,
289 			      unsigned long flags);
290 
291 struct clk *
292 devm_clk_regmap_register_fractional_divider(struct device *dev,
293 					    const char *name,
294 					    const char *parent_name,
295 					    struct regmap *regmap,
296 					    u32 reg, unsigned long flags);
297 
298 struct clk *
299 devm_clk_regmap_register_composite(struct device *dev, const char *name,
300 				   const char *const *parent_names,
301 				   u8 num_parents, struct regmap *regmap,
302 				   u32 mux_reg, u8 mux_shift, u8 mux_width,
303 				   u32 div_reg, u8 div_shift, u8 div_width,
304 				   u8 div_flags,
305 				   u32 gate_reg, u8 gate_shift,
306 				   unsigned long flags);
307 
308 #endif
309