1*9c92ab61SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
24f728b5dSMaxime Ripard /*
34f728b5dSMaxime Ripard * Copyright (c) 2016 Maxime Ripard. All rights reserved.
44f728b5dSMaxime Ripard */
54f728b5dSMaxime Ripard
64f728b5dSMaxime Ripard #ifndef _CCU_NKMP_H_
74f728b5dSMaxime Ripard #define _CCU_NKMP_H_
84f728b5dSMaxime Ripard
94f728b5dSMaxime Ripard #include <linux/clk-provider.h>
104f728b5dSMaxime Ripard
114f728b5dSMaxime Ripard #include "ccu_common.h"
124f728b5dSMaxime Ripard #include "ccu_div.h"
134f728b5dSMaxime Ripard #include "ccu_mult.h"
144f728b5dSMaxime Ripard
154f728b5dSMaxime Ripard /*
164f728b5dSMaxime Ripard * struct ccu_nkmp - Definition of an N-K-M-P clock
174f728b5dSMaxime Ripard *
184f728b5dSMaxime Ripard * Clocks based on the formula parent * N * K >> P / M
194f728b5dSMaxime Ripard */
204f728b5dSMaxime Ripard struct ccu_nkmp {
214f728b5dSMaxime Ripard u32 enable;
224f728b5dSMaxime Ripard u32 lock;
234f728b5dSMaxime Ripard
24a501a14eSMaxime Ripard struct ccu_mult_internal n;
25a501a14eSMaxime Ripard struct ccu_mult_internal k;
26a501a14eSMaxime Ripard struct ccu_div_internal m;
27a501a14eSMaxime Ripard struct ccu_div_internal p;
284f728b5dSMaxime Ripard
29a910f251SIcenowy Zheng unsigned int fixed_post_div;
30a8e5433cSJernej Skrabec unsigned int max_rate;
31a910f251SIcenowy Zheng
324f728b5dSMaxime Ripard struct ccu_common common;
334f728b5dSMaxime Ripard };
344f728b5dSMaxime Ripard
354f728b5dSMaxime Ripard #define SUNXI_CCU_NKMP_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
364f728b5dSMaxime Ripard _nshift, _nwidth, \
374f728b5dSMaxime Ripard _kshift, _kwidth, \
384f728b5dSMaxime Ripard _mshift, _mwidth, \
394f728b5dSMaxime Ripard _pshift, _pwidth, \
404f728b5dSMaxime Ripard _gate, _lock, _flags) \
414f728b5dSMaxime Ripard struct ccu_nkmp _struct = { \
424f728b5dSMaxime Ripard .enable = _gate, \
434f728b5dSMaxime Ripard .lock = _lock, \
444f728b5dSMaxime Ripard .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
454f728b5dSMaxime Ripard .k = _SUNXI_CCU_MULT(_kshift, _kwidth), \
464f728b5dSMaxime Ripard .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
474f728b5dSMaxime Ripard .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
484f728b5dSMaxime Ripard .common = { \
494f728b5dSMaxime Ripard .reg = _reg, \
504f728b5dSMaxime Ripard .hw.init = CLK_HW_INIT(_name, \
514f728b5dSMaxime Ripard _parent, \
524f728b5dSMaxime Ripard &ccu_nkmp_ops, \
534f728b5dSMaxime Ripard _flags), \
544f728b5dSMaxime Ripard }, \
554f728b5dSMaxime Ripard }
564f728b5dSMaxime Ripard
hw_to_ccu_nkmp(struct clk_hw * hw)574f728b5dSMaxime Ripard static inline struct ccu_nkmp *hw_to_ccu_nkmp(struct clk_hw *hw)
584f728b5dSMaxime Ripard {
594f728b5dSMaxime Ripard struct ccu_common *common = hw_to_ccu_common(hw);
604f728b5dSMaxime Ripard
614f728b5dSMaxime Ripard return container_of(common, struct ccu_nkmp, common);
624f728b5dSMaxime Ripard }
634f728b5dSMaxime Ripard
644f728b5dSMaxime Ripard extern const struct clk_ops ccu_nkmp_ops;
654f728b5dSMaxime Ripard
664f728b5dSMaxime Ripard #endif /* _CCU_NKMP_H_ */
67