]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/clk/sunxi-ng/ccu_div.h
Merge branch 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
[karo-tx-linux.git] / drivers / clk / sunxi-ng / ccu_div.h
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 /**
23  * struct ccu_div_internal - Internal divider description
24  * @shift: Bit offset of the divider in its register
25  * @width: Width of the divider field in its register
26  * @max: Maximum value allowed for that divider. This is the
27  *       arithmetic value, not the maximum value to be set in the
28  *       register.
29  * @flags: clk_divider flags to apply on this divider
30  * @table: Divider table pointer (if applicable)
31  *
32  * That structure represents a single divider, and is meant to be
33  * embedded in other structures representing the various clock
34  * classes.
35  *
36  * It is basically a wrapper around the clk_divider functions
37  * arguments.
38  */
39 struct ccu_div_internal {
40         u8                      shift;
41         u8                      width;
42
43         u32                     max;
44         u32                     offset;
45
46         u32                     flags;
47
48         struct clk_div_table    *table;
49 };
50
51 #define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags)      \
52         {                                                               \
53                 .shift  = _shift,                                       \
54                 .width  = _width,                                       \
55                 .flags  = _flags,                                       \
56                 .table  = _table,                                       \
57         }
58
59 #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table)                    \
60         _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
61
62 #define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
63         {                                                               \
64                 .shift  = _shift,                                       \
65                 .width  = _width,                                       \
66                 .flags  = _flags,                                       \
67                 .max    = _max,                                         \
68                 .offset = _off,                                         \
69         }
70
71 #define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags)          \
72         _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
73
74 #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags)                    \
75         _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
76
77 #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max)                        \
78         _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
79
80 #define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset)                  \
81         _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
82
83 #define _SUNXI_CCU_DIV(_shift, _width)                                  \
84         _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
85
86 struct ccu_div {
87         u32                     enable;
88
89         struct ccu_div_internal         div;
90         struct ccu_mux_internal mux;
91         struct ccu_common       common;
92 };
93
94 #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,    \
95                                       _shift, _width,                   \
96                                       _table, _gate, _flags)            \
97         struct ccu_div _struct = {                                      \
98                 .div            = _SUNXI_CCU_DIV_TABLE(_shift, _width,  \
99                                                        _table),         \
100                 .enable         = _gate,                                \
101                 .common = {                                             \
102                         .reg            = _reg,                         \
103                         .hw.init        = CLK_HW_INIT(_name,            \
104                                                       _parent,          \
105                                                       &ccu_div_ops,     \
106                                                       _flags),          \
107                 }                                                       \
108         }
109
110
111 #define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg,              \
112                             _shift, _width,                             \
113                             _table, _flags)                             \
114         SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,    \
115                                       _shift, _width, _table, 0,        \
116                                       _flags)
117
118 #define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,                 \
119                                         _parents, _table,               \
120                                         _reg,                           \
121                                         _mshift, _mwidth,               \
122                                         _muxshift, _muxwidth,           \
123                                         _gate, _flags)                  \
124         struct ccu_div _struct = {                                      \
125                 .enable = _gate,                                        \
126                 .div    = _SUNXI_CCU_DIV(_mshift, _mwidth),             \
127                 .mux    = _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
128                 .common = {                                             \
129                         .reg            = _reg,                         \
130                         .hw.init        = CLK_HW_INIT_PARENTS(_name,    \
131                                                               _parents, \
132                                                               &ccu_div_ops, \
133                                                               _flags),  \
134                 },                                                      \
135         }
136
137 #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg,       \
138                                   _mshift, _mwidth, _muxshift, _muxwidth, \
139                                   _gate, _flags)                        \
140         SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,                 \
141                                         _parents, NULL,                 \
142                                         _reg, _mshift, _mwidth,         \
143                                         _muxshift, _muxwidth,           \
144                                         _gate, _flags)
145
146 #define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg,            \
147                              _mshift, _mwidth, _muxshift, _muxwidth,    \
148                              _flags)                                    \
149         SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,                 \
150                                         _parents, NULL,                 \
151                                         _reg, _mshift, _mwidth,         \
152                                         _muxshift, _muxwidth,           \
153                                         0, _flags)
154
155
156 #define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,            \
157                               _mshift, _mwidth, _gate,                  \
158                               _flags)                                   \
159         struct ccu_div _struct = {                                      \
160                 .enable = _gate,                                        \
161                 .div    = _SUNXI_CCU_DIV(_mshift, _mwidth),             \
162                 .common = {                                             \
163                         .reg            = _reg,                         \
164                         .hw.init        = CLK_HW_INIT(_name,            \
165                                                       _parent,          \
166                                                       &ccu_div_ops,     \
167                                                       _flags),          \
168                 },                                                      \
169         }
170
171 #define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth,    \
172                     _flags)                                             \
173         SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,            \
174                               _mshift, _mwidth, 0, _flags)
175
176 static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
177 {
178         struct ccu_common *common = hw_to_ccu_common(hw);
179
180         return container_of(common, struct ccu_div, common);
181 }
182
183 extern const struct clk_ops ccu_div_ops;
184
185 #endif /* _CCU_DIV_H_ */