Linux 4.18.10
[linux/fpc-iii.git] / drivers / clk / sunxi-ng / ccu_mp.h
blob5107635e61deb500913ccba9ebf25b9fafbc1267
1 /*
2 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
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.
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.
14 #ifndef _CCU_MP_H_
15 #define _CCU_MP_H_
17 #include <linux/bitops.h>
18 #include <linux/clk-provider.h>
20 #include "ccu_common.h"
21 #include "ccu_div.h"
22 #include "ccu_mult.h"
23 #include "ccu_mux.h"
26 * struct ccu_mp - Definition of an M-P clock
28 * Clocks based on the formula parent >> P / M
30 struct ccu_mp {
31 u32 enable;
33 struct ccu_div_internal m;
34 struct ccu_div_internal p;
35 struct ccu_mux_internal mux;
37 unsigned int fixed_post_div;
39 struct ccu_common common;
42 #define SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, _reg, \
43 _mshift, _mwidth, \
44 _pshift, _pwidth, \
45 _muxshift, _muxwidth, \
46 _gate, _postdiv, _flags) \
47 struct ccu_mp _struct = { \
48 .enable = _gate, \
49 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
50 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
51 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
52 .fixed_post_div = _postdiv, \
53 .common = { \
54 .reg = _reg, \
55 .features = CCU_FEATURE_FIXED_POSTDIV, \
56 .hw.init = CLK_HW_INIT_PARENTS(_name, \
57 _parents, \
58 &ccu_mp_ops, \
59 _flags), \
60 } \
63 #define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
64 _mshift, _mwidth, \
65 _pshift, _pwidth, \
66 _muxshift, _muxwidth, \
67 _gate, _flags) \
68 struct ccu_mp _struct = { \
69 .enable = _gate, \
70 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
71 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
72 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
73 .common = { \
74 .reg = _reg, \
75 .hw.init = CLK_HW_INIT_PARENTS(_name, \
76 _parents, \
77 &ccu_mp_ops, \
78 _flags), \
79 } \
82 #define SUNXI_CCU_MP_WITH_MUX(_struct, _name, _parents, _reg, \
83 _mshift, _mwidth, \
84 _pshift, _pwidth, \
85 _muxshift, _muxwidth, \
86 _flags) \
87 SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
88 _mshift, _mwidth, \
89 _pshift, _pwidth, \
90 _muxshift, _muxwidth, \
91 0, _flags)
93 static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw)
95 struct ccu_common *common = hw_to_ccu_common(hw);
97 return container_of(common, struct ccu_mp, common);
100 extern const struct clk_ops ccu_mp_ops;
103 * Special class of M-P clock that supports MMC timing modes
105 * Since the MMC clock registers all follow the same layout, we can
106 * simplify the macro for this particular case. In addition, as
107 * switching modes also affects the output clock rate, we need to
108 * have CLK_GET_RATE_NOCACHE for all these types of clocks.
111 #define SUNXI_CCU_MP_MMC_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
112 _flags) \
113 struct ccu_mp _struct = { \
114 .enable = BIT(31), \
115 .m = _SUNXI_CCU_DIV(0, 4), \
116 .p = _SUNXI_CCU_DIV(16, 2), \
117 .mux = _SUNXI_CCU_MUX(24, 2), \
118 .common = { \
119 .reg = _reg, \
120 .features = CCU_FEATURE_MMC_TIMING_SWITCH, \
121 .hw.init = CLK_HW_INIT_PARENTS(_name, \
122 _parents, \
123 &ccu_mp_mmc_ops, \
124 CLK_GET_RATE_NOCACHE | \
125 _flags), \
129 extern const struct clk_ops ccu_mp_mmc_ops;
131 #endif /* _CCU_MP_H_ */