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