Linux-libre 4.17.3-gnu
[librecmc/linux-libre.git] / drivers / clk / sunxi-ng / ccu_nm.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_NM_H_
15 #define _CCU_NM_H_
16
17 #include <linux/clk-provider.h>
18
19 #include "ccu_common.h"
20 #include "ccu_div.h"
21 #include "ccu_frac.h"
22 #include "ccu_mult.h"
23 #include "ccu_sdm.h"
24
25 /*
26  * struct ccu_nm - Definition of an N-M clock
27  *
28  * Clocks based on the formula parent * N / M
29  */
30 struct ccu_nm {
31         u32                     enable;
32         u32                     lock;
33
34         struct ccu_mult_internal        n;
35         struct ccu_div_internal         m;
36         struct ccu_frac_internal        frac;
37         struct ccu_sdm_internal         sdm;
38
39         unsigned int            fixed_post_div;
40         unsigned int            min_rate;
41
42         struct ccu_common       common;
43 };
44
45 #define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg,  \
46                                         _nshift, _nwidth,               \
47                                         _mshift, _mwidth,               \
48                                         _sdm_table, _sdm_en,            \
49                                         _sdm_reg, _sdm_reg_en,          \
50                                         _gate, _lock, _flags)           \
51         struct ccu_nm _struct = {                                       \
52                 .enable         = _gate,                                \
53                 .lock           = _lock,                                \
54                 .n              = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
55                 .m              = _SUNXI_CCU_DIV(_mshift, _mwidth),     \
56                 .sdm            = _SUNXI_CCU_SDM(_sdm_table, _sdm_en,   \
57                                                  _sdm_reg, _sdm_reg_en),\
58                 .common         = {                                     \
59                         .reg            = _reg,                         \
60                         .features       = CCU_FEATURE_SIGMA_DELTA_MOD,  \
61                         .hw.init        = CLK_HW_INIT(_name,            \
62                                                       _parent,          \
63                                                       &ccu_nm_ops,      \
64                                                       _flags),          \
65                 },                                                      \
66         }
67
68 #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg, \
69                                          _nshift, _nwidth,              \
70                                          _mshift, _mwidth,              \
71                                          _frac_en, _frac_sel,           \
72                                          _frac_rate_0, _frac_rate_1,    \
73                                          _gate, _lock, _flags)          \
74         struct ccu_nm _struct = {                                       \
75                 .enable         = _gate,                                \
76                 .lock           = _lock,                                \
77                 .n              = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
78                 .m              = _SUNXI_CCU_DIV(_mshift, _mwidth),     \
79                 .frac           = _SUNXI_CCU_FRAC(_frac_en, _frac_sel,  \
80                                                   _frac_rate_0,         \
81                                                   _frac_rate_1),        \
82                 .common         = {                                     \
83                         .reg            = _reg,                         \
84                         .features       = CCU_FEATURE_FRACTIONAL,       \
85                         .hw.init        = CLK_HW_INIT(_name,            \
86                                                       _parent,          \
87                                                       &ccu_nm_ops,      \
88                                                       _flags),          \
89                 },                                                      \
90         }
91
92 #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(_struct, _name, _parent,   \
93                                              _reg, _min_rate,           \
94                                              _nshift, _nwidth,          \
95                                              _mshift, _mwidth,          \
96                                              _frac_en, _frac_sel,       \
97                                              _frac_rate_0, _frac_rate_1,\
98                                              _gate, _lock, _flags)      \
99         struct ccu_nm _struct = {                                       \
100                 .enable         = _gate,                                \
101                 .lock           = _lock,                                \
102                 .n              = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
103                 .m              = _SUNXI_CCU_DIV(_mshift, _mwidth),     \
104                 .frac           = _SUNXI_CCU_FRAC(_frac_en, _frac_sel,  \
105                                                   _frac_rate_0,         \
106                                                   _frac_rate_1),        \
107                 .min_rate       = _min_rate,                            \
108                 .common         = {                                     \
109                         .reg            = _reg,                         \
110                         .features       = CCU_FEATURE_FRACTIONAL,       \
111                         .hw.init        = CLK_HW_INIT(_name,            \
112                                                       _parent,          \
113                                                       &ccu_nm_ops,      \
114                                                       _flags),          \
115                 },                                                      \
116         }
117
118 #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg,      \
119                                     _nshift, _nwidth,                   \
120                                     _mshift, _mwidth,                   \
121                                     _gate, _lock, _flags)               \
122         struct ccu_nm _struct = {                                       \
123                 .enable         = _gate,                                \
124                 .lock           = _lock,                                \
125                 .n              = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
126                 .m              = _SUNXI_CCU_DIV(_mshift, _mwidth),     \
127                 .common         = {                                     \
128                         .reg            = _reg,                         \
129                         .hw.init        = CLK_HW_INIT(_name,            \
130                                                       _parent,          \
131                                                       &ccu_nm_ops,      \
132                                                       _flags),          \
133                 },                                                      \
134         }
135
136 static inline struct ccu_nm *hw_to_ccu_nm(struct clk_hw *hw)
137 {
138         struct ccu_common *common = hw_to_ccu_common(hw);
139
140         return container_of(common, struct ccu_nm, common);
141 }
142
143 extern const struct clk_ops ccu_nm_ops;
144
145 #endif /* _CCU_NM_H_ */