1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
9 #include <linux/bitops.h>
10 #include <linux/clk-provider.h>
12 #include "ccu_common.h"
18 * struct ccu_mp - Definition of an M-P clock
20 * Clocks based on the formula parent >> P / M
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, \
37 _muxshift, _muxwidth, \
38 _gate, _postdiv, _flags) \
39 struct ccu_mp _struct = { \
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, \
47 .features = CCU_FEATURE_FIXED_POSTDIV, \
48 .hw.init = CLK_HW_INIT_PARENTS(_name, \
55 #define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
58 _muxshift, _muxwidth, \
60 struct ccu_mp _struct = { \
62 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
63 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
64 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
67 .hw.init = CLK_HW_INIT_PARENTS(_name, \
74 #define SUNXI_CCU_MP_WITH_MUX(_struct, _name, _parents, _reg, \
77 _muxshift, _muxwidth, \
79 SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
82 _muxshift, _muxwidth, \
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, \
105 struct ccu_mp _struct = { \
107 .m = _SUNXI_CCU_DIV(0, 4), \
108 .p = _SUNXI_CCU_DIV(16, 2), \
109 .mux = _SUNXI_CCU_MUX(24, 2), \
112 .features = CCU_FEATURE_MMC_TIMING_SWITCH, \
113 .hw.init = CLK_HW_INIT_PARENTS(_name, \
116 CLK_GET_RATE_NOCACHE | \
121 extern const struct clk_ops ccu_mp_mmc_ops
;
123 #endif /* _CCU_MP_H_ */