1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2016 Maxime Ripard. All rights reserved.
4  */
5 
6 #ifndef _CCU_NKM_H_
7 #define _CCU_NKM_H_
8 
9 #include "ccu.h"
10 #include "ccu_common.h"
11 #include "ccu_div.h"
12 #include "ccu_mult.h"
13 
14 /*
15  * struct ccu_nkm - Definition of an N-K-M clock
16  *
17  * Clocks based on the formula parent * N * K / M
18  */
19 struct ccu_nkm
20 {
21     u32         enable;
22     u32         lock;
23 
24     struct ccu_mult_internal    n;
25     struct ccu_mult_internal    k;
26     struct ccu_div_internal     m;
27     struct ccu_mux_internal mux;
28 
29     unsigned int        fixed_post_div;
30 
31     struct ccu_common   common;
32 };
33 
34 #define SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(_struct, _name, _parents, _reg, \
35         _nshift, _nwidth,      \
36         _kshift, _kwidth,      \
37         _mshift, _mwidth,      \
38         _muxshift, _muxwidth,      \
39         _gate, _lock, _flags)      \
40 struct ccu_nkm _struct = {                  \
41     .enable     = _gate,                \
42                   .lock       = _lock,                \
43                                 .k      = _SUNXI_CCU_MULT(_kshift, _kwidth),    \
44                                           .n      = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
45                                                   .m      = _SUNXI_CCU_DIV(_mshift, _mwidth), \
46                                                           .mux        = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
47                                                                   .common     = {                 \
48                                                                                                   .reg        = _reg,             \
49                                                                                                   .hw.init    = CLK_HW_INIT_PARENTS(_name,    \
50                                                                                                           _parents,     \
51                                                                                                           &ccu_nkm_ops, \
52                                                                                                           _flags),      \
53                                                                                 },                          \
54 }
55 
56 #define SUNXI_CCU_NKM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
57                                      _nshift, _nwidth,          \
58                                      _kshift, _kwidth,          \
59                                      _mshift, _mwidth,          \
60                                      _gate, _lock, _flags)      \
61 struct ccu_nkm _struct = {                  \
62     .enable     = _gate,                \
63                   .lock       = _lock,                \
64                                 .k      = _SUNXI_CCU_MULT(_kshift, _kwidth),    \
65                                           .n      = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
66                                                   .m      = _SUNXI_CCU_DIV(_mshift, _mwidth), \
67                                                           .common     = {                 \
68                                                                                           .reg        = _reg,             \
69                                                                                           .hw.init    = CLK_HW_INIT(_name,        \
70                                                                                                   _parent,      \
71                                                                                                   &ccu_nkm_ops, \
72                                                                                                   _flags),      \
73                                                                         },                          \
74 }
75 
hw_to_ccu_nkm(struct clk_hw * hw)76 static inline struct ccu_nkm *hw_to_ccu_nkm(struct clk_hw *hw)
77 {
78     struct ccu_common *common = hw_to_ccu_common(hw);
79 
80     return container_of(common, struct ccu_nkm, common);
81 }
82 
83 extern const struct clk_ops ccu_nkm_ops;
84 
85 #endif /* _CCU_NKM_H_ */
86