1 // SPDX-License-Identifier: GPL-2.0+
3 // OWL composite clock driver
5 // Copyright (c) 2014 Actions Semi Inc.
6 // Author: David Liu <liuwei@actions-semi.com>
8 // Copyright (c) 2018 Linaro Ltd.
9 // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
11 #include <linux/clk-provider.h>
12 #include <linux/regmap.h>
14 #include "owl-composite.h"
16 static u8
owl_comp_get_parent(struct clk_hw
*hw
)
18 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
20 return owl_mux_helper_get_parent(&comp
->common
, &comp
->mux_hw
);
23 static int owl_comp_set_parent(struct clk_hw
*hw
, u8 index
)
25 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
27 return owl_mux_helper_set_parent(&comp
->common
, &comp
->mux_hw
, index
);
30 static void owl_comp_disable(struct clk_hw
*hw
)
32 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
33 struct owl_clk_common
*common
= &comp
->common
;
35 owl_gate_set(common
, &comp
->gate_hw
, false);
38 static int owl_comp_enable(struct clk_hw
*hw
)
40 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
41 struct owl_clk_common
*common
= &comp
->common
;
43 owl_gate_set(common
, &comp
->gate_hw
, true);
48 static int owl_comp_is_enabled(struct clk_hw
*hw
)
50 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
51 struct owl_clk_common
*common
= &comp
->common
;
53 return owl_gate_clk_is_enabled(common
, &comp
->gate_hw
);
56 static long owl_comp_div_round_rate(struct clk_hw
*hw
, unsigned long rate
,
57 unsigned long *parent_rate
)
59 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
61 return owl_divider_helper_round_rate(&comp
->common
, &comp
->rate
.div_hw
,
65 static unsigned long owl_comp_div_recalc_rate(struct clk_hw
*hw
,
66 unsigned long parent_rate
)
68 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
70 return owl_divider_helper_recalc_rate(&comp
->common
, &comp
->rate
.div_hw
,
74 static int owl_comp_div_set_rate(struct clk_hw
*hw
, unsigned long rate
,
75 unsigned long parent_rate
)
77 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
79 return owl_divider_helper_set_rate(&comp
->common
, &comp
->rate
.div_hw
,
83 static long owl_comp_fact_round_rate(struct clk_hw
*hw
, unsigned long rate
,
84 unsigned long *parent_rate
)
86 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
88 return owl_factor_helper_round_rate(&comp
->common
,
89 &comp
->rate
.factor_hw
,
93 static unsigned long owl_comp_fact_recalc_rate(struct clk_hw
*hw
,
94 unsigned long parent_rate
)
96 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
98 return owl_factor_helper_recalc_rate(&comp
->common
,
99 &comp
->rate
.factor_hw
,
103 static int owl_comp_fact_set_rate(struct clk_hw
*hw
, unsigned long rate
,
104 unsigned long parent_rate
)
106 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
108 return owl_factor_helper_set_rate(&comp
->common
,
109 &comp
->rate
.factor_hw
,
113 static long owl_comp_fix_fact_round_rate(struct clk_hw
*hw
, unsigned long rate
,
114 unsigned long *parent_rate
)
116 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
117 struct clk_fixed_factor
*fix_fact_hw
= &comp
->rate
.fix_fact_hw
;
119 return comp
->fix_fact_ops
->round_rate(&fix_fact_hw
->hw
, rate
, parent_rate
);
122 static unsigned long owl_comp_fix_fact_recalc_rate(struct clk_hw
*hw
,
123 unsigned long parent_rate
)
125 struct owl_composite
*comp
= hw_to_owl_comp(hw
);
126 struct clk_fixed_factor
*fix_fact_hw
= &comp
->rate
.fix_fact_hw
;
128 return comp
->fix_fact_ops
->recalc_rate(&fix_fact_hw
->hw
, parent_rate
);
132 static int owl_comp_fix_fact_set_rate(struct clk_hw
*hw
, unsigned long rate
,
133 unsigned long parent_rate
)
136 * We must report success but we can do so unconditionally because
137 * owl_comp_fix_fact_round_rate returns values that ensure this call is
144 const struct clk_ops owl_comp_div_ops
= {
146 .get_parent
= owl_comp_get_parent
,
147 .set_parent
= owl_comp_set_parent
,
150 .disable
= owl_comp_disable
,
151 .enable
= owl_comp_enable
,
152 .is_enabled
= owl_comp_is_enabled
,
155 .round_rate
= owl_comp_div_round_rate
,
156 .recalc_rate
= owl_comp_div_recalc_rate
,
157 .set_rate
= owl_comp_div_set_rate
,
161 const struct clk_ops owl_comp_fact_ops
= {
163 .get_parent
= owl_comp_get_parent
,
164 .set_parent
= owl_comp_set_parent
,
167 .disable
= owl_comp_disable
,
168 .enable
= owl_comp_enable
,
169 .is_enabled
= owl_comp_is_enabled
,
172 .round_rate
= owl_comp_fact_round_rate
,
173 .recalc_rate
= owl_comp_fact_recalc_rate
,
174 .set_rate
= owl_comp_fact_set_rate
,
177 const struct clk_ops owl_comp_fix_fact_ops
= {
179 .disable
= owl_comp_disable
,
180 .enable
= owl_comp_enable
,
181 .is_enabled
= owl_comp_is_enabled
,
184 .round_rate
= owl_comp_fix_fact_round_rate
,
185 .recalc_rate
= owl_comp_fix_fact_recalc_rate
,
186 .set_rate
= owl_comp_fix_fact_set_rate
,
190 const struct clk_ops owl_comp_pass_ops
= {
192 .get_parent
= owl_comp_get_parent
,
193 .set_parent
= owl_comp_set_parent
,
196 .disable
= owl_comp_disable
,
197 .enable
= owl_comp_enable
,
198 .is_enabled
= owl_comp_is_enabled
,