1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2016 Maxime Ripard. All rights reserved.
4  */
5 
6 #ifndef _CCU_NM_H_
7 #define _CCU_NM_H_
8 
9 #include "ccu.h"
10 #include "ccu_common.h"
11 #include "ccu_div.h"
12 #include "ccu_frac.h"
13 #include "ccu_mult.h"
14 #include "ccu_sdm.h"
15 
16 /*
17  * struct ccu_nm - Definition of an N-M clock
18  *
19  * Clocks based on the formula parent * N / M
20  */
21 struct ccu_nm
22 {
23     u32         enable;
24     u32         lock;
25 
26     struct ccu_mult_internal    n;
27     struct ccu_div_internal     m;
28     struct ccu_frac_internal    frac;
29     struct ccu_sdm_internal     sdm;
30 
31     unsigned int        fixed_post_div;
32     unsigned int        min_rate;
33     unsigned int        max_rate;
34 
35     struct ccu_common   common;
36 };
37 
38 #define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg,  \
39                                         _nshift, _nwidth,       \
40                                         _mshift, _mwidth,       \
41                                         _sdm_table, _sdm_en,        \
42                                         _sdm_reg, _sdm_reg_en,      \
43                                         _gate, _lock, _flags)       \
44 struct ccu_nm _struct = {                   \
45     .enable     = _gate,                \
46                   .lock       = _lock,                \
47                                 .n      = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
48                                           .m      = _SUNXI_CCU_DIV(_mshift, _mwidth), \
49                                                   .sdm        = _SUNXI_CCU_SDM(_sdm_table, _sdm_en,   \
50                                                           _sdm_reg, _sdm_reg_en),\
51                                                           .common     = {                 \
52                                                                                           .reg        = _reg,             \
53                                                                                           .features   = CCU_FEATURE_SIGMA_DELTA_MOD,  \
54                                                                                           .hw.init    = CLK_HW_INIT(_name,        \
55                                                                                                   _parent,      \
56                                                                                                   &ccu_nm_ops,  \
57                                                                                                   _flags),      \
58                                                                         },                          \
59 }
60 
61 #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg, \
62         _nshift, _nwidth,      \
63         _mshift, _mwidth,      \
64         _frac_en, _frac_sel,       \
65         _frac_rate_0, _frac_rate_1,    \
66         _gate, _lock, _flags)      \
67 struct ccu_nm _struct = {                   \
68     .enable     = _gate,                \
69                   .lock       = _lock,                \
70                                 .n      = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
71                                           .m      = _SUNXI_CCU_DIV(_mshift, _mwidth), \
72                                                   .frac       = _SUNXI_CCU_FRAC(_frac_en, _frac_sel,  \
73                                                           _frac_rate_0,     \
74                                                           _frac_rate_1),    \
75                                                           .common     = {                 \
76                                                                                           .reg        = _reg,             \
77                                                                                           .features   = CCU_FEATURE_FRACTIONAL,   \
78                                                                                           .hw.init    = CLK_HW_INIT(_name,        \
79                                                                                                   _parent,      \
80                                                                                                   &ccu_nm_ops,  \
81                                                                                                   _flags),      \
82                                                                         },                          \
83 }
84 
85 #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(_struct, _name, _parent,   \
86         _reg, _min_rate,       \
87         _nshift, _nwidth,      \
88         _mshift, _mwidth,      \
89         _frac_en, _frac_sel,   \
90         _frac_rate_0, _frac_rate_1,\
91         _gate, _lock, _flags)  \
92 struct ccu_nm _struct = {                   \
93     .enable     = _gate,                \
94                   .lock       = _lock,                \
95                                 .n      = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
96                                           .m      = _SUNXI_CCU_DIV(_mshift, _mwidth), \
97                                                   .frac       = _SUNXI_CCU_FRAC(_frac_en, _frac_sel,  \
98                                                           _frac_rate_0,     \
99                                                           _frac_rate_1),    \
100                                                           .min_rate   = _min_rate,                \
101                                                                   .common     = {                 \
102                                                                                                   .reg        = _reg,             \
103                                                                                                   .features   = CCU_FEATURE_FRACTIONAL,   \
104                                                                                                   .hw.init    = CLK_HW_INIT(_name,        \
105                                                                                                           _parent,      \
106                                                                                                           &ccu_nm_ops,  \
107                                                                                                           _flags),      \
108                                                                                 },                          \
109 }
110 
111 #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name,    \
112         _parent, _reg,     \
113         _min_rate, _max_rate,  \
114         _nshift, _nwidth,  \
115         _mshift, _mwidth,  \
116         _frac_en, _frac_sel,   \
117         _frac_rate_0,      \
118         _frac_rate_1,      \
119         _gate, _lock, _flags)  \
120 struct ccu_nm _struct = {                   \
121     .enable     = _gate,                \
122                   .lock       = _lock,                \
123                                 .n      = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
124                                           .m      = _SUNXI_CCU_DIV(_mshift, _mwidth), \
125                                                   .frac       = _SUNXI_CCU_FRAC(_frac_en, _frac_sel,  \
126                                                           _frac_rate_0,     \
127                                                           _frac_rate_1),    \
128                                                           .min_rate   = _min_rate,                \
129                                                                   .max_rate   = _max_rate,                \
130                                                                           .common     = {                 \
131                                                                                                           .reg        = _reg,             \
132                                                                                                           .features   = CCU_FEATURE_FRACTIONAL,   \
133                                                                                                           .hw.init    = CLK_HW_INIT(_name,        \
134                                                                                                                   _parent,      \
135                                                                                                                   &ccu_nm_ops,  \
136                                                                                                                   _flags),      \
137                                                                                         },                          \
138 }
139 
140 #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg,  \
141                                     _nshift, _nwidth,           \
142                                     _mshift, _mwidth,           \
143                                     _gate, _lock, _flags)       \
144 struct ccu_nm _struct = {                   \
145     .enable     = _gate,                \
146                   .lock       = _lock,                \
147                                 .n      = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
148                                           .m      = _SUNXI_CCU_DIV(_mshift, _mwidth), \
149                                                   .common     = {                 \
150                                                                                   .reg        = _reg,             \
151                                                                                   .hw.init    = CLK_HW_INIT(_name,        \
152                                                                                           _parent,      \
153                                                                                           &ccu_nm_ops,  \
154                                                                                           _flags),      \
155                                                                 },                          \
156 }
157 
hw_to_ccu_nm(struct clk_hw * hw)158 static inline struct ccu_nm *hw_to_ccu_nm(struct clk_hw *hw)
159 {
160     struct ccu_common *common = hw_to_ccu_common(hw);
161 
162     return container_of(common, struct ccu_nm, common);
163 }
164 
165 extern const struct clk_ops ccu_nm_ops;
166 
167 #endif /* _CCU_NM_H_ */
168