WIP FPC-III support
[linux/fpc-iii.git] / drivers / clk / sunxi-ng / ccu_mp.h
blobb392e0d575b5c4107b494091c916a1232cb23574
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
4 */
6 #ifndef _CCU_MP_H_
7 #define _CCU_MP_H_
9 #include <linux/bitops.h>
10 #include <linux/clk-provider.h>
12 #include "ccu_common.h"
13 #include "ccu_div.h"
14 #include "ccu_mult.h"
15 #include "ccu_mux.h"
18 * struct ccu_mp - Definition of an M-P clock
20 * Clocks based on the formula parent >> P / M
22 struct ccu_mp {
23 u32 enable;
25 struct ccu_div_internal m;
26 struct ccu_div_internal p;
27 struct ccu_mux_internal mux;
29 unsigned int fixed_post_div;
31 struct ccu_common common;
34 #define SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, _reg, \
35 _mshift, _mwidth, \
36 _pshift, _pwidth, \
37 _muxshift, _muxwidth, \
38 _gate, _postdiv, _flags) \
39 struct ccu_mp _struct = { \
40 .enable = _gate, \
41 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
42 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
43 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
44 .fixed_post_div = _postdiv, \
45 .common = { \
46 .reg = _reg, \
47 .features = CCU_FEATURE_FIXED_POSTDIV, \
48 .hw.init = CLK_HW_INIT_PARENTS(_name, \
49 _parents, \
50 &ccu_mp_ops, \
51 _flags), \
52 } \
55 #define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
56 _mshift, _mwidth, \
57 _pshift, _pwidth, \
58 _muxshift, _muxwidth, \
59 _gate, _flags) \
60 struct ccu_mp _struct = { \
61 .enable = _gate, \
62 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
63 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
64 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
65 .common = { \
66 .reg = _reg, \
67 .hw.init = CLK_HW_INIT_PARENTS(_name, \
68 _parents, \
69 &ccu_mp_ops, \
70 _flags), \
71 } \
74 #define SUNXI_CCU_MP_WITH_MUX(_struct, _name, _parents, _reg, \
75 _mshift, _mwidth, \
76 _pshift, _pwidth, \
77 _muxshift, _muxwidth, \
78 _flags) \
79 SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
80 _mshift, _mwidth, \
81 _pshift, _pwidth, \
82 _muxshift, _muxwidth, \
83 0, _flags)
85 static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw)
87 struct ccu_common *common = hw_to_ccu_common(hw);
89 return container_of(common, struct ccu_mp, common);
92 extern const struct clk_ops ccu_mp_ops;
95 * Special class of M-P clock that supports MMC timing modes
97 * Since the MMC clock registers all follow the same layout, we can
98 * simplify the macro for this particular case. In addition, as
99 * switching modes also affects the output clock rate, we need to
100 * have CLK_GET_RATE_NOCACHE for all these types of clocks.
103 #define SUNXI_CCU_MP_MMC_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
104 _flags) \
105 struct ccu_mp _struct = { \
106 .enable = BIT(31), \
107 .m = _SUNXI_CCU_DIV(0, 4), \
108 .p = _SUNXI_CCU_DIV(16, 2), \
109 .mux = _SUNXI_CCU_MUX(24, 2), \
110 .common = { \
111 .reg = _reg, \
112 .features = CCU_FEATURE_MMC_TIMING_SWITCH, \
113 .hw.init = CLK_HW_INIT_PARENTS(_name, \
114 _parents, \
115 &ccu_mp_mmc_ops, \
116 CLK_GET_RATE_NOCACHE | \
117 _flags), \
121 extern const struct clk_ops ccu_mp_mmc_ops;
123 #endif /* _CCU_MP_H_ */