xref: /openbmc/linux/drivers/clk/sunxi-ng/ccu_div.h (revision 1491eaf9)
1 /*
2  * Copyright (c) 2016 Maxime Ripard. All rights reserved.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 
14 #ifndef _CCU_DIV_H_
15 #define _CCU_DIV_H_
16 
17 #include <linux/clk-provider.h>
18 
19 #include "ccu_common.h"
20 #include "ccu_mux.h"
21 
22 struct _ccu_div {
23 	u8			shift;
24 	u8			width;
25 
26 	u32			flags;
27 
28 	struct clk_div_table	*table;
29 };
30 
31 #define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags)	\
32 	{								\
33 		.shift	= _shift,					\
34 		.width	= _width,					\
35 		.flags	= _flags,					\
36 		.table	= _table,					\
37 	}
38 
39 #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags)			\
40 	_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, _flags)
41 
42 #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table)			\
43 	_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
44 
45 #define _SUNXI_CCU_DIV(_shift, _width)					\
46 	_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, 0)
47 
48 struct ccu_div {
49 	u32			enable;
50 
51 	struct _ccu_div		div;
52 	struct ccu_mux_internal	mux;
53 	struct ccu_common	common;
54 };
55 
56 #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,	\
57 				      _shift, _width,			\
58 				      _table, _gate, _flags)		\
59 	struct ccu_div _struct = {					\
60 		.div		= _SUNXI_CCU_DIV_TABLE(_shift, _width,	\
61 						       _table),		\
62 		.enable		= _gate,				\
63 		.common	= {						\
64 			.reg		= _reg,				\
65 			.hw.init	= CLK_HW_INIT(_name,		\
66 						      _parent,		\
67 						      &ccu_div_ops,	\
68 						      _flags),		\
69 		}							\
70 	}
71 
72 
73 #define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg,		\
74 			    _shift, _width,				\
75 			    _table, _flags)				\
76 	SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,	\
77 				      _shift, _width, _table, 0,	\
78 				      _flags)
79 
80 #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
81 				  _mshift, _mwidth, _muxshift, _muxwidth, \
82 				  _gate, _flags)			\
83 	struct ccu_div _struct = {					\
84 		.enable	= _gate,					\
85 		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
86 		.mux	= SUNXI_CLK_MUX(_muxshift, _muxwidth),		\
87 		.common	= {						\
88 			.reg		= _reg,				\
89 			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
90 							      _parents, \
91 							      &ccu_div_ops, \
92 							      _flags),	\
93 		},							\
94 	}
95 
96 #define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg,		\
97 			     _mshift, _mwidth, _muxshift, _muxwidth,	\
98 			     _flags)					\
99 	SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
100 				  _mshift, _mwidth, _muxshift, _muxwidth, \
101 				  0, _flags)
102 
103 
104 #define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\
105 			      _mshift, _mwidth,	_gate,			\
106 			      _flags)					\
107 	struct ccu_div _struct = {					\
108 		.enable	= _gate,					\
109 		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
110 		.common	= {						\
111 			.reg		= _reg,				\
112 			.hw.init	= CLK_HW_INIT(_name,		\
113 						      _parent,		\
114 						      &ccu_div_ops,	\
115 						      _flags),		\
116 		},							\
117 	}
118 
119 #define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth,	\
120 		    _flags)						\
121 	SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\
122 			      _mshift, _mwidth, 0, _flags)
123 
124 static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
125 {
126 	struct ccu_common *common = hw_to_ccu_common(hw);
127 
128 	return container_of(common, struct ccu_div, common);
129 }
130 
131 extern const struct clk_ops ccu_div_ops;
132 
133 #endif /* _CCU_DIV_H_ */
134