1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | // |
3 | // OWL composite clock driver |
4 | // |
5 | // Copyright (c) 2014 Actions Semi Inc. |
6 | // Author: David Liu <liuwei@actions-semi.com> |
7 | // |
8 | // Copyright (c) 2018 Linaro Ltd. |
9 | // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
10 | |
11 | #ifndef _OWL_COMPOSITE_H_ |
12 | #define _OWL_COMPOSITE_H_ |
13 | |
14 | #include "owl-common.h" |
15 | #include "owl-mux.h" |
16 | #include "owl-gate.h" |
17 | #include "owl-factor.h" |
18 | #include "owl-fixed-factor.h" |
19 | #include "owl-divider.h" |
20 | |
21 | union owl_rate { |
22 | struct owl_divider_hw div_hw; |
23 | struct owl_factor_hw factor_hw; |
24 | struct clk_fixed_factor fix_fact_hw; |
25 | }; |
26 | |
27 | struct owl_composite { |
28 | struct owl_mux_hw mux_hw; |
29 | struct owl_gate_hw gate_hw; |
30 | union owl_rate rate; |
31 | |
32 | const struct clk_ops *fix_fact_ops; |
33 | |
34 | struct owl_clk_common common; |
35 | }; |
36 | |
37 | #define OWL_COMP_DIV(_struct, _name, _parent, \ |
38 | _mux, _gate, _div, _flags) \ |
39 | struct owl_composite _struct = { \ |
40 | .mux_hw = _mux, \ |
41 | .gate_hw = _gate, \ |
42 | .rate.div_hw = _div, \ |
43 | .common = { \ |
44 | .regmap = NULL, \ |
45 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ |
46 | _parent, \ |
47 | &owl_comp_div_ops,\ |
48 | _flags), \ |
49 | }, \ |
50 | } |
51 | |
52 | #define OWL_COMP_DIV_FIXED(_struct, _name, _parent, \ |
53 | _gate, _div, _flags) \ |
54 | struct owl_composite _struct = { \ |
55 | .gate_hw = _gate, \ |
56 | .rate.div_hw = _div, \ |
57 | .common = { \ |
58 | .regmap = NULL, \ |
59 | .hw.init = CLK_HW_INIT(_name, \ |
60 | _parent, \ |
61 | &owl_comp_div_ops,\ |
62 | _flags), \ |
63 | }, \ |
64 | } |
65 | |
66 | #define OWL_COMP_FACTOR(_struct, _name, _parent, \ |
67 | _mux, _gate, _factor, _flags) \ |
68 | struct owl_composite _struct = { \ |
69 | .mux_hw = _mux, \ |
70 | .gate_hw = _gate, \ |
71 | .rate.factor_hw = _factor, \ |
72 | .common = { \ |
73 | .regmap = NULL, \ |
74 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ |
75 | _parent, \ |
76 | &owl_comp_fact_ops,\ |
77 | _flags), \ |
78 | }, \ |
79 | } |
80 | |
81 | #define OWL_COMP_FIXED_FACTOR(_struct, _name, _parent, \ |
82 | _gate, _mul, _div, _flags) \ |
83 | struct owl_composite _struct = { \ |
84 | .gate_hw = _gate, \ |
85 | .rate.fix_fact_hw.mult = _mul, \ |
86 | .rate.fix_fact_hw.div = _div, \ |
87 | .fix_fact_ops = &clk_fixed_factor_ops, \ |
88 | .common = { \ |
89 | .regmap = NULL, \ |
90 | .hw.init = CLK_HW_INIT(_name, \ |
91 | _parent, \ |
92 | &owl_comp_fix_fact_ops,\ |
93 | _flags), \ |
94 | }, \ |
95 | } |
96 | |
97 | #define OWL_COMP_PASS(_struct, _name, _parent, \ |
98 | _mux, _gate, _flags) \ |
99 | struct owl_composite _struct = { \ |
100 | .mux_hw = _mux, \ |
101 | .gate_hw = _gate, \ |
102 | .common = { \ |
103 | .regmap = NULL, \ |
104 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ |
105 | _parent, \ |
106 | &owl_comp_pass_ops,\ |
107 | _flags), \ |
108 | }, \ |
109 | } |
110 | |
111 | static inline struct owl_composite *hw_to_owl_comp(const struct clk_hw *hw) |
112 | { |
113 | struct owl_clk_common *common = hw_to_owl_clk_common(hw); |
114 | |
115 | return container_of(common, struct owl_composite, common); |
116 | } |
117 | |
118 | extern const struct clk_ops owl_comp_div_ops; |
119 | extern const struct clk_ops owl_comp_fact_ops; |
120 | extern const struct clk_ops owl_comp_fix_fact_ops; |
121 | extern const struct clk_ops owl_comp_pass_ops; |
122 | extern const struct clk_ops clk_fixed_factor_ops; |
123 | |
124 | #endif /* _OWL_COMPOSITE_H_ */ |
125 | |